We run! We finally run!
This commit is contained in:
parent
ec533526df
commit
a22d91903f
10 changed files with 315 additions and 41 deletions
|
@ -75,7 +75,7 @@ void kputs(const char *str);
|
||||||
* @param format The format string that will be printed in formatted version.
|
* @param format The format string that will be printed in formatted version.
|
||||||
* @param ... The format parameters that will be used to print the string.
|
* @param ... The format parameters that will be used to print the string.
|
||||||
*/
|
*/
|
||||||
void kprintf(const char *format, ...);
|
void kprintf(const char *format, ...) __attribute__((format(printf,1,2)));
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace ker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Pair<Key, Value> Entry;
|
typedef Pair<Key, Value> Entry;
|
||||||
private:
|
public:
|
||||||
Vector<Entry> contents;
|
Vector<Entry> contents;
|
||||||
public:
|
public:
|
||||||
Dictionary() :
|
Dictionary() :
|
||||||
|
@ -19,6 +19,24 @@ namespace ker
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dictionary(const Dictionary &other) :
|
||||||
|
contents(other.contents)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary(Dictionary &&other) :
|
||||||
|
contents(other.contents)
|
||||||
|
{
|
||||||
|
other.contents = Vector<Entry>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary & operator = (const Dictionary &other)
|
||||||
|
{
|
||||||
|
this->contents = other.contents;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
Value &at(const Key &key)
|
Value &at(const Key &key)
|
||||||
{
|
{
|
||||||
for(auto &&pair : this->contents)
|
for(auto &&pair : this->contents)
|
||||||
|
@ -39,6 +57,15 @@ namespace ker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value get(const Key &key) const
|
||||||
|
{
|
||||||
|
if(this->contains(key)) {
|
||||||
|
return this->at(key);
|
||||||
|
} else {
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool contains(const Key &key) const
|
bool contains(const Key &key) const
|
||||||
{
|
{
|
||||||
for(const auto &pair : this->contents)
|
for(const auto &pair : this->contents)
|
||||||
|
|
|
@ -16,5 +16,27 @@ namespace ker
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pair(const Pair &other) :
|
||||||
|
first(other.first),
|
||||||
|
second(other.second)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair(Pair &&other) :
|
||||||
|
first(other.first),
|
||||||
|
second(other.second)
|
||||||
|
{
|
||||||
|
other.first = First();
|
||||||
|
other.second = Second();
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair & operator = (const Pair &other)
|
||||||
|
{
|
||||||
|
this->first = other.first;
|
||||||
|
this->second = other.second;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,29 +34,22 @@ namespace ker
|
||||||
|
|
||||||
String & operator = (const String &other)
|
String & operator = (const String &other)
|
||||||
{
|
{
|
||||||
free(this->mText);
|
this->copyFrom(other.mText, other.mLength);
|
||||||
this->mLength = other.mLength;
|
return *this;
|
||||||
|
|
||||||
this->mText = (uint8_t*)malloc(this->mLength + 1);
|
|
||||||
memcpy(this->mText, other.mText, this->mLength + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String(const char *text) :
|
String(const char *text) :
|
||||||
mText(nullptr),
|
mText(nullptr),
|
||||||
mLength(0)
|
mLength(0)
|
||||||
{
|
{
|
||||||
this->mLength = strlen(text);
|
this->copyFrom(reinterpret_cast<const uint8_t*>(text), strlen(text));
|
||||||
this->mText = (uint8_t*)malloc(this->mLength + 1);
|
|
||||||
memcpy(this->mText, text, this->mLength);
|
|
||||||
this->mText[this->mLength] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String(const uint8_t *bytes, size_t length) :
|
String(const uint8_t *bytes, size_t length) :
|
||||||
mText((uint8_t*)malloc(length + 1)),
|
mText(nullptr),
|
||||||
mLength(length)
|
mLength(length)
|
||||||
{
|
{
|
||||||
memcpy(this->mText, bytes, length);
|
this->copyFrom(bytes, length);
|
||||||
this->mText[this->mLength] = 0; // last byte is always 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~String()
|
~String()
|
||||||
|
@ -76,7 +69,7 @@ namespace ker
|
||||||
if(this->mLength != other.mLength) {
|
if(this->mLength != other.mLength) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return memcmp(this->mText, other.mText, this->mLength) != 0;
|
return memcmp(this->mText, other.mText, this->mLength) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *text() const
|
const uint8_t *text() const
|
||||||
|
@ -123,5 +116,16 @@ namespace ker
|
||||||
{
|
{
|
||||||
return !this->equals(other);
|
return !this->equals(other);
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
|
void copyFrom(const uint8_t *bytes, size_t length)
|
||||||
|
{
|
||||||
|
if(this->mText != nullptr) {
|
||||||
|
free(this->mText);
|
||||||
|
}
|
||||||
|
this->mText = (uint8_t*)malloc(length + 1);
|
||||||
|
memcpy(this->mText, bytes, length);
|
||||||
|
this->mLength = length;
|
||||||
|
this->mText[this->mLength] = 0; // last byte is always 0
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,12 +23,53 @@ namespace ker
|
||||||
this->reserve(Vector<T>::initialCap);
|
this->reserve(Vector<T>::initialCap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector(const Vector &other) :
|
||||||
|
mData(nullptr),
|
||||||
|
mLength(0),
|
||||||
|
mReserved(0)
|
||||||
|
{
|
||||||
|
this->mLength = other.mLength;
|
||||||
|
if(this->mLength > 0) {
|
||||||
|
this->reserve(this->mLength);
|
||||||
|
for(size_t i = 0; i < this->mLength; i++) {
|
||||||
|
new (&this->mData[i]) T(other.mData[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector(Vector &&other) :
|
||||||
|
mData(other.mData),
|
||||||
|
mLength(other.mLength),
|
||||||
|
mReserved(other.mReserved)
|
||||||
|
{
|
||||||
|
other.mData = nullptr;
|
||||||
|
other.mLength = 0;
|
||||||
|
other.mReserved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector & operator = (const Vector &other)
|
||||||
|
{
|
||||||
|
this->resize(other.mLength);
|
||||||
|
for(size_t i = 0; i < this->mLength; i++)
|
||||||
|
{
|
||||||
|
this->mData[i] = other.mData[i];
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
explicit Vector(size_t initialReserve) :
|
explicit Vector(size_t initialReserve) :
|
||||||
Vector()
|
Vector()
|
||||||
{
|
{
|
||||||
this->reserve(initialReserve);
|
this->reserve(initialReserve);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~Vector()
|
||||||
|
{
|
||||||
|
if(this->mData != nullptr) {
|
||||||
|
free(this->mData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t length() const
|
size_t length() const
|
||||||
{
|
{
|
||||||
return this->mLength;
|
return this->mLength;
|
||||||
|
@ -47,7 +88,7 @@ namespace ker
|
||||||
void append(const T &value)
|
void append(const T &value)
|
||||||
{
|
{
|
||||||
this->reserve(this->mLength + 1);
|
this->reserve(this->mLength + 1);
|
||||||
new (&this->mData[this->mLength - 1]) T(value);
|
new (&this->mData[this->mLength]) T(value);
|
||||||
this->mLength += 1;
|
this->mLength += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +108,7 @@ namespace ker
|
||||||
new (&this->mData[i]) T ();
|
new (&this->mData[i]) T ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this->mLength = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reserve(size_t space)
|
void reserve(size_t space)
|
||||||
|
@ -82,6 +124,7 @@ namespace ker
|
||||||
free(this->mData);
|
free(this->mData);
|
||||||
}
|
}
|
||||||
this->mData = newData;
|
this->mData = newData;
|
||||||
|
this->mReserved = space;
|
||||||
}
|
}
|
||||||
|
|
||||||
T& operator [](size_t idx)
|
T& operator [](size_t idx)
|
||||||
|
|
|
@ -219,4 +219,4 @@ void kprintf(const char *format, ...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
}
|
}
|
||||||
|
|
200
src/vm.cpp
200
src/vm.cpp
|
@ -10,17 +10,120 @@ extern "C" {
|
||||||
// extern size_t file01_size;
|
// extern size_t file01_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
char file01[] = "VAR global : INT;\0";
|
char file01[] = R"code(
|
||||||
|
VAR global : INT;
|
||||||
|
PUB main() | i : INT
|
||||||
|
BEGIN
|
||||||
|
print(10, 20, 30);
|
||||||
|
0 -> i;
|
||||||
|
REPEAT
|
||||||
|
BEGIN
|
||||||
|
print(i);
|
||||||
|
i + 1 -> i;
|
||||||
|
END
|
||||||
|
END)code";
|
||||||
|
|
||||||
|
void cpp_test();
|
||||||
|
|
||||||
|
class PrintMethod :
|
||||||
|
public Method
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Variable invoke(Vector<Variable> arguments) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
Variable PrintMethod::invoke(Vector<Variable> arguments)
|
||||||
|
{
|
||||||
|
for(auto &var : arguments)
|
||||||
|
{
|
||||||
|
var.printval();
|
||||||
|
kprintf(" ");
|
||||||
|
}
|
||||||
|
kprintf("\n");
|
||||||
|
return Variable::Void;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void vm_start()
|
||||||
|
{
|
||||||
|
// cpp_test();
|
||||||
|
|
||||||
|
kprintf("Parse kernel module: ");
|
||||||
|
Module *module = VM::load(file01, sizeof(file01) - 1);
|
||||||
|
if(module == nullptr) {
|
||||||
|
kprintf("Could not load module :(\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf("Module successfully loaded :)\n");
|
||||||
|
|
||||||
|
module->methods.add("print", new PrintMethod());
|
||||||
|
|
||||||
|
for(const auto &var : module->variables)
|
||||||
|
{
|
||||||
|
kprintf("Variable: '%s' => '", var.first.str());
|
||||||
|
var.second->printval();
|
||||||
|
kprintf("'\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const auto &fn : module->methods)
|
||||||
|
{
|
||||||
|
kprintf("Function: '%s'\n", fn.first.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
Method *main = module->method("main");
|
||||||
|
if(main == nullptr) {
|
||||||
|
kprintf("Script has no main method.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
main->invoke({ });
|
||||||
|
|
||||||
|
delete module;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String fn()
|
String fn()
|
||||||
{
|
{
|
||||||
return String("keks");
|
return String("keks");
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void vm_start()
|
void put(Vector<int> &v)
|
||||||
|
{
|
||||||
|
kprintf("v[%d]: ", v.length());
|
||||||
|
for(int i : v) { kprintf("%d,", i); }
|
||||||
|
kprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void put(Vector<String> &v)
|
||||||
|
{
|
||||||
|
kprintf("v[%d]: ", v.length());
|
||||||
|
for(String &s : v) { kprintf("[%s],", s.str()); }
|
||||||
|
kprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void put(Dictionary<int, int> &d)
|
||||||
|
{
|
||||||
|
kprintf("dict: ");
|
||||||
|
for(auto &it : d)
|
||||||
|
{
|
||||||
|
kprintf("[%d -> %d] ", it.first, it.second);
|
||||||
|
}
|
||||||
|
kprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void put(Dictionary<String, String> &d)
|
||||||
|
{
|
||||||
|
kprintf("dict: ");
|
||||||
|
for(auto &it : d)
|
||||||
|
{
|
||||||
|
kprintf("[%s -> %s] ", it.first.str(), it.second.str());
|
||||||
|
}
|
||||||
|
kprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cpp_test()
|
||||||
{
|
{
|
||||||
kprintf("Testing ker::String:\n");
|
kprintf("Testing ker::String:\n");
|
||||||
|
|
||||||
{
|
{
|
||||||
String a("hello");
|
String a("hello");
|
||||||
String b(a);
|
String b(a);
|
||||||
|
@ -33,20 +136,89 @@ extern "C" void vm_start()
|
||||||
kprintf("'%s' '%s' '%s' '%s' '%s'\n", a.str(), b.str(), c.str(), d.str(), e.str());
|
kprintf("'%s' '%s' '%s' '%s' '%s'\n", a.str(), b.str(), c.str(), d.str(), e.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kprintf("Testing ker::Pair:\n");
|
||||||
|
{
|
||||||
|
Pair<int, int> a(10, 20);
|
||||||
|
Pair<String, String> b("Hey", "Affe");
|
||||||
|
|
||||||
kprintf("Parse kernel module:");
|
Pair<int, int> c(a);
|
||||||
Module *module = VM::load(file01, sizeof(file01));
|
Pair<String, String> d(b);
|
||||||
if(module == nullptr) {
|
|
||||||
kprintf("Could not load module :(\n");
|
Pair<int, int> e; e = a;
|
||||||
return;
|
Pair<String, String> f; f = b;
|
||||||
|
|
||||||
|
kprintf("'%d,%d' '%d,%d' '%d,%d'\n", a.first, a.second, c.first, c.second, e.first, e.second);
|
||||||
|
kprintf("'%s,%s' '%s,%s' '%s,%s'\n", b.first.str(), b.second.str(), d.first.str(), d.second.str(), f.first.str(), f.second.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
kprintf("Module successfully loaded :)\n");
|
kprintf("Testing ker::Vector:\n");
|
||||||
|
|
||||||
for(const auto &var : module->variables)
|
|
||||||
{
|
{
|
||||||
kprintf("Variable: '%s' => '");
|
Vector<int> a;
|
||||||
var.second->printval();
|
a.append(1);
|
||||||
kprintf("\n");
|
a.append(2);
|
||||||
|
a.append(3);
|
||||||
|
|
||||||
|
Vector<int> c;
|
||||||
|
Vector<int> b(a);
|
||||||
|
c = a;
|
||||||
|
|
||||||
|
put(a);
|
||||||
|
put(b);
|
||||||
|
put(c);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Vector<String> a;
|
||||||
|
a.append("x");
|
||||||
|
a.append("y");
|
||||||
|
a.append("z");
|
||||||
|
|
||||||
|
Vector<String> c;
|
||||||
|
Vector<String> b(a);
|
||||||
|
c = a;
|
||||||
|
|
||||||
|
put(a);
|
||||||
|
put(b);
|
||||||
|
put(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf("Testing ker::Dictionary:\n");
|
||||||
|
{
|
||||||
|
kprintf("int -> int\n");
|
||||||
|
Dictionary<int, int> a;
|
||||||
|
a.add(1, 30);
|
||||||
|
a.add(2, 20);
|
||||||
|
a.add(3, 10);
|
||||||
|
|
||||||
|
kprintf("%d %d\n", a.contains(1), a.contains(4));
|
||||||
|
kprintf("%d %d\n", a.at(1), a.at(3));
|
||||||
|
kprintf("%d %d\n", a[1], a[3]);
|
||||||
|
|
||||||
|
Dictionary<int, int> b(a);
|
||||||
|
Dictionary<int, int> c;
|
||||||
|
c = a;
|
||||||
|
|
||||||
|
put(a);
|
||||||
|
put(b);
|
||||||
|
put(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
kprintf("String -> String\n");
|
||||||
|
Dictionary<String, String> a;
|
||||||
|
a.add("x", "30");
|
||||||
|
a.add("y", "20");
|
||||||
|
a.add("z", "10");
|
||||||
|
|
||||||
|
kprintf("%d %d\n", a.contains("x"), a.contains("w"));
|
||||||
|
kprintf("%s %s\n", a.at("x").str(), a.at("z").str());
|
||||||
|
kprintf("%s %s\n", a["x"].str(), a["z"].str());
|
||||||
|
|
||||||
|
Dictionary<String, String> b(a);
|
||||||
|
Dictionary<String, String> c;
|
||||||
|
c = a;
|
||||||
|
|
||||||
|
put(a);
|
||||||
|
put(b);
|
||||||
|
put(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ input:
|
||||||
using namespace trainscript;
|
using namespace trainscript;
|
||||||
auto *mod = context->module;
|
auto *mod = context->module;
|
||||||
|
|
||||||
Method *method = new Method(mod, $2.body);
|
ScriptMethod *method = new ScriptMethod(mod, $2.body);
|
||||||
method->isPublic = $2.header.isPublic;
|
method->isPublic = $2.header.isPublic;
|
||||||
if($2.header.returnValue) {
|
if($2.header.returnValue) {
|
||||||
method->returnValue = ker::Pair<ker::String, Variable>(
|
method->returnValue = ker::Pair<ker::String, Variable>(
|
||||||
|
|
|
@ -42,9 +42,7 @@ namespace trainscript
|
||||||
data.module = module;
|
data.module = module;
|
||||||
yylex_init_extra(&data, &data.scanner);
|
yylex_init_extra(&data, &data.scanner);
|
||||||
|
|
||||||
int error = yyparse(&data);
|
bool valid = yyparse(&data) == 0;
|
||||||
kprintf("[E:%d]", error);
|
|
||||||
bool valid = error == 0;
|
|
||||||
|
|
||||||
yylex_destroy(data.scanner);
|
yylex_destroy(data.scanner);
|
||||||
free(internalStorage);
|
free(internalStorage);
|
||||||
|
@ -78,7 +76,7 @@ namespace trainscript
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable Method::invoke(ker::Vector<Variable> arguments)
|
Variable ScriptMethod::invoke(ker::Vector<Variable> arguments)
|
||||||
{
|
{
|
||||||
LocalContext context(this->module);
|
LocalContext context(this->module);
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,15 @@ namespace trainscript
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Method
|
class Method
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Method() { }
|
||||||
|
virtual Variable invoke(ker::Vector<Variable> arguments) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScriptMethod :
|
||||||
|
public Method
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Module *module;
|
Module *module;
|
||||||
|
@ -174,12 +182,12 @@ namespace trainscript
|
||||||
ker::Dictionary<ker::String, Variable> locals;
|
ker::Dictionary<ker::String, Variable> locals;
|
||||||
ker::Pair<ker::String, Variable> returnValue;
|
ker::Pair<ker::String, Variable> returnValue;
|
||||||
|
|
||||||
Method(Module *module, Instruction *block) : module(module), block(block)
|
ScriptMethod(Module *module, Instruction *block) : module(module), block(block)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable invoke(ker::Vector<Variable> arguments);
|
Variable invoke(ker::Vector<Variable> arguments) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Module
|
class Module
|
||||||
|
@ -193,12 +201,12 @@ namespace trainscript
|
||||||
|
|
||||||
Method *method(const char *name)
|
Method *method(const char *name)
|
||||||
{
|
{
|
||||||
return this->methods[name];
|
return this->methods.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable *variable(const char *name)
|
Variable *variable(const char *name)
|
||||||
{
|
{
|
||||||
return this->variables[name];
|
return this->variables.get(name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue