Adds better debugging output. Also adds a return; to free :P

This commit is contained in:
Felix Queissner 2015-08-16 23:40:34 +02:00
parent 2faadc29e9
commit d55ff69193
17 changed files with 175 additions and 82 deletions

View file

@ -40,7 +40,7 @@ obj/console.o: src/console.c include/console.h include/stdlib.h \
# src/init.c
obj/init.o: src/init.c include/kernel.h include/stdlib.h include/varargs.h \
include/console.h include/interrupts.h include/cpustate.h include/pmm.h \
include/multiboot.h include/vmm.h include/timer.h
include/multiboot.h include/vmm.h include/config.h include/timer.h
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/init.c
# src/interrupts.c
@ -69,8 +69,9 @@ obj/timer.o: src/timer.c include/timer.h include/kernel.h \
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/timer.c
# src/vmm.c
obj/vmm.o: src/vmm.c include/vmm.h include/pmm.h include/multiboot.h \
include/stdlib.h include/varargs.h include/console.h include/kernel.h
obj/vmm.o: src/vmm.c include/config.h include/vmm.h include/pmm.h \
include/multiboot.h include/stdlib.h include/varargs.h include/console.h \
include/kernel.h
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/vmm.c
# trainscript/tsvm.cpp

5
include/config.h Normal file
View file

@ -0,0 +1,5 @@
#pragma once
/*
#define USE_VIRTUAL_MEMORY_MANAGEMENT
//*/

View file

@ -46,12 +46,6 @@ namespace ker
this->copyFrom(bytes, length);
}
String & operator = (const String &other)
{
this->copyFrom(other.mText, other.mLength);
return *this;
}
~String()
{
if(this->mText != nullptr) {
@ -82,11 +76,6 @@ namespace ker
return cat;
}
static String concat(const String &lhs, const String &rhs)
{
return lhs.append(rhs);
}
const uint8_t *text() const
{
static const uint8_t empty[] = { 0 };
@ -122,6 +111,12 @@ namespace ker
return this->mText[index];
}
String & operator = (const String &other)
{
this->copyFrom(other.mText, other.mLength);
return *this;
}
bool operator ==(const String &other) const
{
return this->equals(other);
@ -131,6 +126,12 @@ namespace ker
{
return !this->equals(other);
}
String operator +(const String &other) const
{
return this->append(other);
}
private:
void copyFrom(const uint8_t *bytes, size_t length)
{
@ -142,6 +143,18 @@ namespace ker
this->mLength = length;
this->mText[this->mLength] = 0; // last byte is always 0
}
public:
static String concat(const String &lhs, const String &rhs)
{
return lhs.append(rhs);
}
static String fromNumber(int32_t number, int radix = 10)
{
static char buffer[64];
itoa(number, buffer, radix);
return String(buffer);
}
};

View file

@ -8,6 +8,8 @@ extern "C" {
void die(const char *msg);
void die_extra(const char *msg, const char *extra);
#if defined(__cplusplus)
}
#endif

View file

@ -95,6 +95,28 @@ static inline size_t strlen(const char *str)
return size;
}
static inline int strcmp(const char *p1, const char *p2)
{
while(*p1) {
if(*p2 == 0) {
return 1;
}
if(*p2 > *p1) {
return -1;
}
if(*p1 > *p2) {
return 1;
}
p1++;
p2++;
}
if (*p2) {
return -1;
}
return 0;
}
static inline void *calloc(size_t size)
{
void *mem = malloc(size);

View file

@ -1,11 +1,14 @@
#pragma once
#include <inttypes.h>
#include <config.h>
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(USE_VIRTUAL_MEMORY_MANAGEMENT)
#define VM_PRESENT 0x01
#define VM_WRITABLE 0x02
#define VM_USER 0x04
@ -24,6 +27,8 @@ void vmm_init(void);
*/
void vmm_map(uintptr_t virtual, uintptr_t physical, uint32_t flags);
#endif
#if defined(__cplusplus)
}
#endif

View file

@ -3,11 +3,10 @@ VAR global : INT;
PUB main() | i : INT
BEGIN
0 -> i;
# Print numbers from 1 to 5
WHILE ((i + 1) -> i) <= 5 DO
WHILE ((i + 1) -> i) <= 50 DO
BEGIN
printInt(i);
sleep(20);
sleep(2);
END
END

View file

@ -4,18 +4,28 @@
#include <interrupts.h>
#include <pmm.h>
#include <vmm.h>
#include <timer.h>
#include <config.h>
void die(const char *msg)
{
kputs("\n");
ksetcolor(COLOR_RED, COLOR_WHITE);
kputs(msg);
while(1)
{
__asm__ volatile ("cli; hlt;");
}
die_extra(msg, "");
}
void die_extra(const char *msg, const char *extra)
{
kputs("\n");
ksetcolor(COLOR_RED, COLOR_WHITE);
kputs(msg);
if((extra != nullptr) && (strlen(extra) > 0)) {
kputs(": '");
kputs(extra);
kputc('\'');
}
while(1)
{
__asm__ volatile ("cli; hlt;");
}
}
extern size_t mallocCount;
@ -156,12 +166,14 @@ void init(const MultibootStructure *mbHeader)
pmm_init(mbHeader);
putsuccess();
// uint32_t freeMem = pmm_calc_free();
//kprintf("Free memory: %d B, %d kB, %d MB\n", freeMem, freeMem >> 10, freeMem >> 20);
uint32_t freeMem = pmm_calc_free();
kprintf("Free memory: %d B, %d kB, %d MB\n", freeMem, freeMem >> 10, freeMem >> 20);
kputs("Initialize virtual memory management: ");
#if defined(USE_VIRTUAL_MEMORY_MANAGEMENT)
kputs("Initialize virtual memory management: ");
vmm_init();
putsuccess();
#endif
kputs("Initialize interrupts:");
intr_init();
@ -171,12 +183,14 @@ void init(const MultibootStructure *mbHeader)
irq_enable();
putsuccess();
#if defined(USE_VIRTUAL_MEMORY_MANAGEMENT)
kputs("Prepare heap memory:");
for(uintptr_t ptr = 0x400000; ptr < 0x800000; ptr += 4096)
for(uintptr_t ptr = 0x400000; ptr < 0x800000; ptr += 4096)
{
vmm_map(ptr, (uintptr_t)pmm_alloc(), VM_PROGRAM);
}
putsuccess();
#endif
kputs("Initialize timer:");
timer_init();
@ -188,8 +202,6 @@ void init(const MultibootStructure *mbHeader)
timer_add_callback(1, update_statusbar);
debug_test();
vm_start();
kputs("\x12\x04trainOS stopped.\x12\x07!\n");

View file

@ -173,7 +173,10 @@ void *malloc(size_t len)
void free(void *p)
{
freeCount++;
freeCount++;
return;
struct __freelist *fp1, *fp2, *fpnew;
char *cp1, *cp2, *cpnew;

View file

@ -66,7 +66,7 @@ Variable NativeMethod::invoke(Vector<Variable> arguments)
case TypeID::Bool: stackSize += sizeof(Int); break;
case TypeID::Int: stackSize += sizeof(Int); break;
case TypeID::Real: stackSize += sizeof(Real); break;
default: die("invalid argument type."); break;
default: die_extra("NativeMethod.InvalidArgument", arguments[i].type.name()); break;
}
}
@ -85,7 +85,6 @@ Variable NativeMethod::invoke(Vector<Variable> arguments)
*reinterpret_cast<Real*>(stack) = arguments[i].real;
stack += sizeof(Real);
break;
default: die("invalid argument type."); break;
}
}

View file

@ -1,8 +1,11 @@
#include "vmm.h"
#include "pmm.h"
#include "stdlib.h"
#include "console.h"
#include "kernel.h"
#include <config.h>
#include <vmm.h>
#include <pmm.h>
#include <stdlib.h>
#include <console.h>
#include <kernel.h>
#if defined(USE_VIRTUAL_MEMORY_MANAGEMENT)
typedef struct
{
@ -79,3 +82,5 @@ void vmm_init(void)
cr0 |= (1 << 31);
__asm__ volatile("mov %0, %%cr0" : : "r" (cr0));
}
#endif

View file

@ -39,7 +39,8 @@ HEADERS += \
include/ker/dictionary.hpp \
include/string.h \
include/ker/new.hpp \
include/dynamic.h
include/dynamic.h \
include/config.h
DISTFILES += \
asm/intr_common_handler.S \

View file

@ -21,14 +21,29 @@ void yyerror(void *scanner, const char *s);
} \
}
typedef struct
struct ParserData
{
char *buffer;
size_t index;
size_t length;
trainscript::Module *module;
void *scanner;
} ParserData;
char* strings[256];
char *strdup(const char *str)
{
for(size_t i = 0; i < 256; i++) {
if(this->strings[i] == nullptr) {
return this->strings[i] = ::strdup(str);
}
else if(strcmp(this->strings[i], str) == 0) {
return this->strings[i];
}
}
die_extra("ParserData::strdup", "out of strings");
}
};
struct VariableDeclaration
{

View file

@ -58,7 +58,7 @@ WHILE { return KW_WHILE; }
DO { return KW_DO; }
[0-9]+\.[0-9]* { yylval->fval = atof(yytext); return REAL; }
[0-9]+ { yylval->ival = atoi(yytext); return INT; }
[a-zA-Z0-9'_]+ { yylval->text = strdup(yytext); return IDENTIFIER; }
[a-zA-Z0-9'_]+ { yylval->text = yyextra->strdup(yytext); return IDENTIFIER; }
. { yyerror(NULL, "illegal token"); }
%%
/*

View file

@ -58,6 +58,12 @@ namespace trainscript
yylex_destroy(data.scanner);
free(internalStorage);
for(size_t i = 0; i < 256; i++) {
if(data.strings[i] != nullptr) {
free(data.strings[i]);
}
}
if(valid) {
return module;
} else {
@ -104,11 +110,11 @@ namespace trainscript
context.add(this->mReturnValue.first, &returnVariable);
}
if(arguments.length() != this->mArguments.length()) {
return Variable::Invalid;
die_extra("ScriptMethod::invoke", "Invalid argument count.");
}
for(size_t i = 0; i < this->mArguments.length(); i++) {
if(this->mArguments[i].second != arguments[i].type) {
return Variable::Invalid;
die_extra("ScriptMethod::invoke", "Invalid argument type.");
}
context.add(this->mArguments[i].first, new Variable(arguments[i]));
}
@ -176,7 +182,7 @@ namespace trainscript
switch(lhs.type.id) {
case TypeID::Int:return mkvar(lhs.integer + rhs.integer);
case TypeID::Real: return mkvar(lhs.real + rhs.real);
default: kprintf("addition not supported for %s.\n", typeName(lhs.type.id)); return Variable::Invalid;
default: kprintf("addition not supported for %s.\n", lhs.type.name()); return Variable::Invalid;
}
}
@ -185,7 +191,7 @@ namespace trainscript
switch(lhs.type.id) {
case TypeID::Int: return mkvar(lhs.integer - rhs.integer);
case TypeID::Real:return mkvar(lhs.real - rhs.real);
default: kprintf("subtraction not supported for %s.\n", typeName(lhs.type.id)); return Variable::Invalid;
default: kprintf("subtraction not supported for %s.\n", lhs.type.name()); return Variable::Invalid;
}
}
@ -194,7 +200,7 @@ namespace trainscript
switch(lhs.type.id) {
case TypeID::Int: return mkvar(lhs.integer * rhs.integer);
case TypeID::Real: return mkvar(lhs.real * rhs.real);
default: kprintf("multiplication not supported for %s.\n", typeName(lhs.type.id)); return Variable::Invalid;
default: kprintf("multiplication not supported for %s.\n", lhs.type.name()); return Variable::Invalid;
}
}
@ -203,7 +209,7 @@ namespace trainscript
switch(lhs.type.id) {
case TypeID::Int: return mkvar(lhs.integer / rhs.integer);
case TypeID::Real: return mkvar(lhs.real / rhs.real);
default: kprintf("division not supported for %s.\n", typeName(lhs.type.id)); return Variable::Invalid;
default: kprintf("division not supported for %s.\n", lhs.type.name()); return Variable::Invalid;
}
}
@ -212,7 +218,7 @@ namespace trainscript
switch(lhs.type.id) {
case TypeID::Int: return mkvar(lhs.integer % rhs.integer);
// case TypeID::Real: mkvar(lhs.real % rhs.real);
default: kprintf("modulo not supported for %s.\n", typeName(lhs.type.id)); return Variable::Invalid;
default: kprintf("modulo not supported for %s.\n", lhs.type.name()); return Variable::Invalid;
}
}
@ -223,7 +229,7 @@ namespace trainscript
case TypeID::Real: return mkbool(lhs.real == rhs.real);
case TypeID::Bool: return mkbool(lhs.boolean == rhs.boolean);
default:
kprintf("equals not supported for %s.\n", typeName(lhs.type.id));
kprintf("equals not supported for %s.\n", lhs.type.name());
return Variable::Invalid;
}
}
@ -235,7 +241,7 @@ namespace trainscript
case TypeID::Real: return mkbool(lhs.real != rhs.real);
case TypeID::Bool: return mkbool(lhs.boolean != rhs.boolean);
default:
kprintf("inequals not supported for %s.\n", typeName(lhs.type.id));
kprintf("inequals not supported for %s.\n", lhs.type.name());
return Variable::Invalid;
}
}
@ -247,7 +253,7 @@ namespace trainscript
case TypeID::Int: return mkbool(lhs.integer < rhs.integer);
case TypeID::Real: return mkbool(lhs.real < rhs.real);
default:
kprintf("equals not supported for %s.\n", typeName(lhs.type.id));
kprintf("equals not supported for %s.\n", lhs.type.name());
return Variable::Invalid;
}
}
@ -258,7 +264,7 @@ namespace trainscript
case TypeID::Int: return mkbool(lhs.integer <= rhs.integer);
case TypeID::Real: return mkbool(lhs.real <= rhs.real);
default:
kprintf("equals not supported for %s.\n", typeName(lhs.type.id));
kprintf("equals not supported for %s.\n", lhs.type.name());
return Variable::Invalid;
}
}
@ -269,7 +275,7 @@ namespace trainscript
case TypeID::Int: return mkbool(lhs.integer > rhs.integer);
case TypeID::Real: return mkbool(lhs.real > rhs.real);
default:
kprintf("equals not supported for %s.\n", typeName(lhs.type.id));
kprintf("equals not supported for %s.\n", lhs.type.name());
return Variable::Invalid;
}
}
@ -280,7 +286,7 @@ namespace trainscript
case TypeID::Int: return mkbool(lhs.integer >= rhs.integer);
case TypeID::Real: return mkbool(lhs.real >= rhs.real);
default:
kprintf("equals not supported for %s.\n", typeName(lhs.type.id));
kprintf("equals not supported for %s.\n", lhs.type.name());
return Variable::Invalid;
}
}

View file

@ -54,6 +54,18 @@ namespace trainscript
(this->pointer != other.pointer);
}
const char *name() const {
switch(id) {
case TypeID::Invalid: return "INVALID";
case TypeID::Void: return "VOID";
case TypeID::Int: return "INT";
case TypeID::Real: return "REAL";
case TypeID::Text: return "TEXT";
case TypeID::Bool: return "BOOL";
default: return "unknown";
}
}
static const Type Invalid;
static const Type Void;
static const Type Int;
@ -288,7 +300,7 @@ namespace trainscript
Variable execute(LocalContext &context) const override {
auto *var = context.get(this->variableName);
if(var == nullptr) {
return Variable::Invalid;
die_extra("VariableExpression.VariableNotFound", this->variableName.str());
}
return *var;
}
@ -328,17 +340,17 @@ namespace trainscript
Variable execute(LocalContext &context) const override {
if(this->expression == nullptr) {
return Variable::Invalid;
die("VariableAssignmentExpression.ExpressionMissing");
}
Variable result = this->expression->execute(context);
Variable *target = context.get(this->variableName);
if(target == nullptr) {
return Variable::Invalid;
die_extra("VariableAssignmentExpression.VariableNotFound", this->variableName.str());
}
if(target->type != result.type) {
return Variable::Invalid;
die_extra("VariableAssignmentExpression.ExpectedType", result.type.name());
}
switch(target->type.id) {
@ -406,7 +418,7 @@ namespace trainscript
{
Method *method = context.module->method(this->methodName.str());
if(method == nullptr) {
return Variable::Invalid;
die_extra("MethodInvokeExpression.MethodNotFound", this->methodName.str());
}
ker::Vector<Variable> vars(this->parameters.length());
@ -467,20 +479,25 @@ namespace trainscript
Variable execute(LocalContext &context) const override {
if(this->lhs == nullptr) {
return Variable::Invalid;
die_extra("ArithmeticExpression.ExpressionMissing", "Left-hand side");
}
if(this->rhs == nullptr) {
return Variable::Invalid;
die_extra("ArithmeticExpression.ExpressionMissing", "Right-hand side");
}
Variable left = this->lhs->execute(context);
Variable right = this->rhs->execute(context);
if(left.type != right.type) {
return Variable::Invalid;
die("ArithmeticExpression.TypeMismatch");
}
return OP(left, right);
Variable result = OP(left, right);
if(result.type.usable() == false) {
die_extra("ArithmeticExpression.InvalidResult", result.type.name());
}
return result;
}
bool validate(LocalContext &context, ker::String &errorCode) const override {
@ -543,12 +560,12 @@ namespace trainscript
Variable execute(LocalContext &context) const override {
if(this->condition == nullptr) {
return Variable::Invalid;
die("IfExpression.ConditionMissing");
}
Variable result = this->condition->execute(context);
if(result.type != Type::Boolean) {
return Variable::Invalid;
die_extra("IfExpression.TypeMismatch", result.type.name());
}
if((result.boolean == true) && (this->blockTrue != nullptr)) {
this->blockTrue->execute(context);
@ -574,7 +591,7 @@ namespace trainscript
Variable execute(LocalContext &context) const override {
if(this->block == nullptr) {
return Variable::Invalid;
die("RepeatEndlessExpression.BlockMissing");
}
while(true)
@ -603,10 +620,10 @@ namespace trainscript
Variable execute(LocalContext &context) const override {
if(this->condition == nullptr) {
return Variable::Invalid;
die("RepeatWhileExpression.ConditionMissing");
}
if(this->block == nullptr) {
return Variable::Invalid;
die("RepeatWhileExpression.BlockMissing");
}
while(true)

View file

@ -11,16 +11,4 @@ namespace trainscript
Text = 4,
Bool = 5,
};
static const char *typeName(TypeID id) {
switch(id) {
case TypeID::Invalid: return "INVALID";
case TypeID::Void: return "VOID";
case TypeID::Int: return "INT";
case TypeID::Real: return "REAL";
case TypeID::Text: return "TEXT";
case TypeID::Bool: return "BOOL";
default: return "unknown";
}
}
}