Skip to content

Commit

Permalink
s3air
Browse files Browse the repository at this point in the history
  • Loading branch information
CCIGAMES committed Mar 2, 2024
1 parent 5923f4e commit b88d6fb
Show file tree
Hide file tree
Showing 14 changed files with 2,180 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Part of the Oxygen Engine / Sonic 3 A.I.R. software distribution.
* Copyright (C) 2017-2024 by Eukaryot
*
* Published under the GNU GPLv3 open source software license, see license.txt
* or https://www.gnu.org/licenses/gpl-3.0.en.html
*/

#include "lemon/pch.h"
#include "lemon/program/StringRef.h"


namespace lemon
{
void StringLookup::addFromList(const std::vector<FlyweightString>& list)
{
for (FlyweightString str : list)
{
addString(str);
}
}
}
41 changes: 41 additions & 0 deletions sonic3air-main/Oxygen/lemonscript/source/lemon/program/StringRef.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Part of the Oxygen Engine / Sonic 3 A.I.R. software distribution.
* Copyright (C) 2017-2024 by Eukaryot
*
* Published under the GNU GPLv3 open source software license, see license.txt
* or https://www.gnu.org/licenses/gpl-3.0.en.html
*/

#pragma once

#include "lemon/utility/FlyweightString.h"


namespace lemon
{

class API_EXPORT StringLookup
{
public:
inline size_t size() const { return mStrings.size(); }

inline void clear() { mStrings.clear(); }
inline const FlyweightString* getStringByHash(uint64 hash) const { return mapFind(mStrings, hash); }
inline void addString(FlyweightString str) { mStrings[str.getHash()] = str; }
inline void addString(std::string_view str, uint64 hash) { mStrings[hash] = str; }

void addFromList(const std::vector<FlyweightString>& list);

private:
std::unordered_map<uint64, FlyweightString> mStrings;
};


struct API_EXPORT StringRef : public FlyweightString
{
inline StringRef() : FlyweightString() {}
inline explicit StringRef(uint64 hash) : FlyweightString(hash) {}
inline explicit StringRef(FlyweightString str) : FlyweightString(str) {}
};

}
113 changes: 113 additions & 0 deletions sonic3air-main/Oxygen/lemonscript/source/lemon/program/Variable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Part of the Oxygen Engine / Sonic 3 A.I.R. software distribution.
* Copyright (C) 2017-2024 by Eukaryot
*
* Published under the GNU GPLv3 open source software license, see license.txt
* or https://www.gnu.org/licenses/gpl-3.0.en.html
*/

#pragma once

#include "lemon/program/DataType.h"
#include "lemon/utility/FlyweightString.h"

#include <functional>


namespace lemon
{
class Environment;


class API_EXPORT Variable
{
friend class Module;
friend class Runtime;
friend class ScriptFunction;

public:
enum class Type : uint8
{
LOCAL = 0, // Variable IDs 0x00000000...0x0fffffff
GLOBAL = 1, // Variable IDs 0x10000000...0x1fffffff
USER = 2, // Variable IDs 0x20000000...0x2fffffff
EXTERNAL = 3 // Variable IDs 0x30000000...0x3fffffff
};

public:
virtual int64 getValue() const = 0;
virtual void setValue(int64 value) = 0;

inline Type getType() const { return mType; }
inline FlyweightString getName() const { return mName; }
inline uint32 getID() const { return mID; }
inline const DataTypeDefinition* getDataType() const { return mDataType; }
inline size_t getStaticMemoryOffset() const { return mStaticMemoryOffset; }
inline size_t getStaticMemorySize() const { return mStaticMemorySize; }

protected:
inline Variable(Type type) : mType(type) {}

private:
Type mType;
FlyweightString mName;
uint32 mID = 0;
const DataTypeDefinition* mDataType = nullptr;
size_t mStaticMemoryOffset = 0;
size_t mStaticMemorySize = 0;
};


class API_EXPORT LocalVariable : public Variable
{
public:
inline LocalVariable() : Variable(Type::LOCAL) {}

// Do not use these for variables, instead look it up in the current state's variables stack
int64 getValue() const override { return 0; }
void setValue(int64 value) override {}
};


class API_EXPORT GlobalVariable : public Variable
{
public:
inline GlobalVariable() : Variable(Type::GLOBAL) {}

// Do not use these for variables, instead look it up in the runtime's global variables list
int64 getValue() const override { return 0; }
void setValue(int64 value) override {}

public:
int64 mInitialValue = 0;
};


class API_EXPORT UserDefinedVariable : public Variable
{
public:
inline UserDefinedVariable() : Variable(Type::USER) {}

int64 getValue() const override { return (mGetter) ? mGetter() : 0; }
void setValue(int64 value) override { if (mSetter) mSetter(value); }

public:
std::function<int64()> mGetter;
std::function<void(int64)> mSetter;
};


class API_EXPORT ExternalVariable : public Variable
{
public:
inline ExternalVariable() : Variable(Type::EXTERNAL) {}

// Do not use these for variables, instead directly access the pointer with the right data type
int64 getValue() const override { return 0; }
void setValue(int64 value) override {}

public:
std::function<int64*()> mAccessor;
};

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* Part of the Oxygen Engine / Sonic 3 A.I.R. software distribution.
* Copyright (C) 2017-2024 by Eukaryot
*
* Published under the GNU GPLv3 open source software license, see license.txt
* or https://www.gnu.org/licenses/gpl-3.0.en.html
*/

#include "lemon/pch.h"
#include "lemon/runtime/BuiltInFunctions.h"
#include "lemon/runtime/FastStringStream.h"
#include "lemon/program/FunctionWrapper.h"
#include "lemon/program/Module.h"
#include "lemon/program/Program.h"


namespace lemon
{
namespace builtins
{
template<typename T>
T constant_array_access(uint32 id, uint32 index)
{
Runtime* runtime = Runtime::getActiveRuntime();
RMX_ASSERT(nullptr != runtime, "No lemon script runtime active");
const std::vector<ConstantArray*>& constantArrays = runtime->getProgram().getConstantArrays();
RMX_CHECK(id < constantArrays.size(), "Invalid constant array ID " << id << " (must be below " << constantArrays.size() << ")", return 0);
return (T)constantArrays[id]->getElement(index);
}

template<>
StringRef constant_array_access(uint32 id, uint32 index)
{
Runtime* runtime = Runtime::getActiveRuntime();
RMX_ASSERT(nullptr != runtime, "No lemon script runtime active");
const std::vector<ConstantArray*>& constantArrays = runtime->getProgram().getConstantArrays();
RMX_CHECK(id < constantArrays.size(), "Invalid constant array ID " << id << " (must be below " << constantArrays.size() << ")", return StringRef());
return StringRef(constantArrays[id]->getElement(index));
}

StringRef string_operator_plus(StringRef str1, StringRef str2)
{
Runtime* runtime = Runtime::getActiveRuntime();
RMX_ASSERT(nullptr != runtime, "No lemon script runtime active");
RMX_CHECK(str1.isValid(), "Unable to resolve string", return StringRef());
RMX_CHECK(str2.isValid(), "Unable to resolve string", return StringRef());

static detail::FastStringStream result;
result.clear();
result.addString(str1.getStringRef());
result.addString(str2.getStringRef());
return StringRef(runtime->addString(std::string_view(result.mBuffer, result.mLength)));
}

StringRef string_operator_plus_int64(StringRef str, int64 value)
{
Runtime* runtime = Runtime::getActiveRuntime();
RMX_ASSERT(nullptr != runtime, "No lemon script runtime active");
RMX_CHECK(str.isValid(), "Unable to resolve string", return StringRef());

static detail::FastStringStream result;
result.clear();
result.addString(str.getStringRef());
result.addDecimal(value, 0);
return StringRef(runtime->addString(std::string_view(result.mBuffer, result.mLength)));
}

StringRef string_operator_plus_int64_inv(int64 value, StringRef str)
{
Runtime* runtime = Runtime::getActiveRuntime();
RMX_ASSERT(nullptr != runtime, "No lemon script runtime active");
RMX_CHECK(str.isValid(), "Unable to resolve string", return StringRef());

static detail::FastStringStream result;
result.clear();
result.addDecimal(value, 0);
result.addString(str.getStringRef());
return StringRef(runtime->addString(std::string_view(result.mBuffer, result.mLength)));
}

bool string_operator_less(StringRef str1, StringRef str2)
{
RMX_CHECK(str1.isValid(), "Unable to resolve string", return false);
RMX_CHECK(str2.isValid(), "Unable to resolve string", return false);
return (str1.getString() < str2.getString());
}

bool string_operator_less_or_equal(StringRef str1, StringRef str2)
{
RMX_CHECK(str1.isValid(), "Unable to resolve string", return false);
RMX_CHECK(str2.isValid(), "Unable to resolve string", return false);
return (str1.getString() <= str2.getString());
}

bool string_operator_greater(StringRef str1, StringRef str2)
{
RMX_CHECK(str1.isValid(), "Unable to resolve string", return false);
RMX_CHECK(str2.isValid(), "Unable to resolve string", return false);
return (str1.getString() > str2.getString());
}

bool string_operator_greater_or_equal(StringRef str1, StringRef str2)
{
RMX_CHECK(str1.isValid(), "Unable to resolve string", return false);
RMX_CHECK(str2.isValid(), "Unable to resolve string", return false);
return (str1.getString() >= str2.getString());
}
}



BuiltInFunctions::FunctionName BuiltInFunctions::CONSTANT_ARRAY_ACCESS("#builtin_constant_array_access");
BuiltInFunctions::FunctionName BuiltInFunctions::STRING_OPERATOR_PLUS("#builtin_string_operator_plus");
BuiltInFunctions::FunctionName BuiltInFunctions::STRING_OPERATOR_PLUS_INT64("#builtin_string_operator_plus_int64");
BuiltInFunctions::FunctionName BuiltInFunctions::STRING_OPERATOR_PLUS_INT64_INV("#builtin_string_operator_plus_int64_inv");
BuiltInFunctions::FunctionName BuiltInFunctions::STRING_OPERATOR_LESS("#builtin_string_operator_less");
BuiltInFunctions::FunctionName BuiltInFunctions::STRING_OPERATOR_LESS_OR_EQUAL("#builtin_string_operator_less_equal");
BuiltInFunctions::FunctionName BuiltInFunctions::STRING_OPERATOR_GREATER("#builtin_string_operator_greater");
BuiltInFunctions::FunctionName BuiltInFunctions::STRING_OPERATOR_GREATER_OR_EQUAL("#builtin_string_operator_greater_equal");


void BuiltInFunctions::registerBuiltInFunctions(lemon::Module& module)
{
// Register built-in functions, which are directly referenced by the compiler
const BitFlagSet<Function::Flag> defaultFlags(Function::Flag::ALLOW_INLINE_EXECUTION);

module.addNativeFunction(CONSTANT_ARRAY_ACCESS.makeFlyweightString(), lemon::wrap(&builtins::constant_array_access<int8>), defaultFlags);
module.addNativeFunction(CONSTANT_ARRAY_ACCESS.makeFlyweightString(), lemon::wrap(&builtins::constant_array_access<uint8>), defaultFlags);
module.addNativeFunction(CONSTANT_ARRAY_ACCESS.makeFlyweightString(), lemon::wrap(&builtins::constant_array_access<int16>), defaultFlags);
module.addNativeFunction(CONSTANT_ARRAY_ACCESS.makeFlyweightString(), lemon::wrap(&builtins::constant_array_access<uint16>), defaultFlags);
module.addNativeFunction(CONSTANT_ARRAY_ACCESS.makeFlyweightString(), lemon::wrap(&builtins::constant_array_access<int32>), defaultFlags);
module.addNativeFunction(CONSTANT_ARRAY_ACCESS.makeFlyweightString(), lemon::wrap(&builtins::constant_array_access<uint32>), defaultFlags);
module.addNativeFunction(CONSTANT_ARRAY_ACCESS.makeFlyweightString(), lemon::wrap(&builtins::constant_array_access<int64>), defaultFlags);
module.addNativeFunction(CONSTANT_ARRAY_ACCESS.makeFlyweightString(), lemon::wrap(&builtins::constant_array_access<uint64>), defaultFlags);
module.addNativeFunction(CONSTANT_ARRAY_ACCESS.makeFlyweightString(), lemon::wrap(&builtins::constant_array_access<StringRef>), defaultFlags);

module.addNativeFunction(STRING_OPERATOR_PLUS.makeFlyweightString(), lemon::wrap(&builtins::string_operator_plus), defaultFlags);
module.addNativeFunction(STRING_OPERATOR_PLUS_INT64.makeFlyweightString(), lemon::wrap(&builtins::string_operator_plus_int64), defaultFlags);
module.addNativeFunction(STRING_OPERATOR_PLUS_INT64_INV.makeFlyweightString(), lemon::wrap(&builtins::string_operator_plus_int64_inv), defaultFlags);
module.addNativeFunction(STRING_OPERATOR_LESS.makeFlyweightString(), lemon::wrap(&builtins::string_operator_less), defaultFlags);
module.addNativeFunction(STRING_OPERATOR_LESS_OR_EQUAL.makeFlyweightString(), lemon::wrap(&builtins::string_operator_less_or_equal), defaultFlags);
module.addNativeFunction(STRING_OPERATOR_GREATER.makeFlyweightString(), lemon::wrap(&builtins::string_operator_greater), defaultFlags);
module.addNativeFunction(STRING_OPERATOR_GREATER_OR_EQUAL.makeFlyweightString(), lemon::wrap(&builtins::string_operator_greater_or_equal), defaultFlags);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Part of the Oxygen Engine / Sonic 3 A.I.R. software distribution.
* Copyright (C) 2017-2024 by Eukaryot
*
* Published under the GNU GPLv3 open source software license, see license.txt
* or https://www.gnu.org/licenses/gpl-3.0.en.html
*/

#pragma once

#include "lemon/utility/FlyweightString.h"


namespace lemon
{
class Module;

class API_EXPORT BuiltInFunctions
{
public:
struct FunctionName
{
std::string mName;
uint64 mHash = 0;

inline explicit FunctionName(const std::string& name) : mName(name), mHash(rmx::getMurmur2_64(name)) {}

inline FlyweightString makeFlyweightString() const { FlyweightString str; str.set(mHash, mName); return str; }
};

public:
static FunctionName CONSTANT_ARRAY_ACCESS;
static FunctionName STRING_OPERATOR_PLUS;
static FunctionName STRING_OPERATOR_PLUS_INT64;
static FunctionName STRING_OPERATOR_PLUS_INT64_INV;
static FunctionName STRING_OPERATOR_LESS;
static FunctionName STRING_OPERATOR_LESS_OR_EQUAL;
static FunctionName STRING_OPERATOR_GREATER;
static FunctionName STRING_OPERATOR_GREATER_OR_EQUAL;

public:
static void registerBuiltInFunctions(Module& module);
};
}
Loading

0 comments on commit b88d6fb

Please sign in to comment.