forked from Xeeynamo/sonic-hybrid-rsdk
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
2,180 additions
and
0 deletions.
There are no files selected for viewing
22 changes: 22 additions & 0 deletions
22
sonic3air-main/Oxygen/lemonscript/source/lemon/program/StringRef.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
41
sonic3air-main/Oxygen/lemonscript/source/lemon/program/StringRef.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
113
sonic3air-main/Oxygen/lemonscript/source/lemon/program/Variable.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}; | ||
|
||
} |
145 changes: 145 additions & 0 deletions
145
sonic3air-main/Oxygen/lemonscript/source/lemon/runtime/BuiltInFunctions.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
sonic3air-main/Oxygen/lemonscript/source/lemon/runtime/BuiltInFunctions.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}; | ||
} |
Oops, something went wrong.