We run! We finally run!

This commit is contained in:
Felix Queißner 2015-08-13 20:12:09 +02:00
parent ec533526df
commit a22d91903f
10 changed files with 315 additions and 41 deletions

View file

@ -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)
} }

View file

@ -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)

View file

@ -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;
}
}; };
} }

View file

@ -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
}
}; };
}; };

View file

@ -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)

View file

@ -219,4 +219,4 @@ void kprintf(const char *format, ...)
} }
} }
va_end(vl); va_end(vl);
} }

View file

@ -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);
} }
} }

View file

@ -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>(

View file

@ -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);

View file

@ -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);
} }
}; };