summaryrefslogtreecommitdiff
path: root/evaluate.h
diff options
context:
space:
mode:
Diffstat (limited to 'evaluate.h')
-rw-r--r--evaluate.h91
1 files changed, 85 insertions, 6 deletions
diff --git a/evaluate.h b/evaluate.h
index 9c50b24..50166cd 100644
--- a/evaluate.h
+++ b/evaluate.h
@@ -1,5 +1,6 @@
#pragma once
+#include <iostream>
#include <string>
#include <unordered_map>
#include "ast.h"
@@ -7,29 +8,48 @@
using namespace std;
+class CompilationError : public runtime_error{
+public:
+ explicit CompilationError(const string &what_arg);
+ explicit CompilationError(const char *what_arg);
+ CompilationError(Site site,const string &what_arg);
+};
+
+class ExecutionError : public runtime_error{
+public:
+ explicit ExecutionError(const string &what_arg);
+ explicit ExecutionError(const char *what_arg);
+};
+
+
class ScopeVal;
class Value{
public:
enum class Type{
- number,
- string,
- scope,
+ nil,
+ number, // numval
+ string, // strval
+ scope, // scopeval
};
Type type;
double numval;
string strval;
- ScopeVal *scope;
+ ScopeVal *scopeval;
+ Value();
Value(double numval);
Value(const string &strval);
- Value(ScopeVal *scope);
+ Value(ScopeVal *scopeval);
};
class ScopeVal{
public:
+ ScopeDef scopeDef;
unordered_map<string,Value> values;
+
+ ScopeVal(const ScopeDef &scopeDef);
};
@@ -41,7 +61,66 @@ namespace A {
template <typename T>
void unref(T *value);
+ void unref_all();
+
}
-void evaluateSTL(const StatementList &stl);
+class Assembly{
+ class Instruction{
+ public:
+ enum class Type{ // Effect on the value stack is given
+ pushnil, // [ -> nil]
+ pushnum, // [ -> this.num]
+ pushstr, // [ -> this.str]
+ pushscope, // [ -> this.scope]
+ pop, // [x -> ]
+ swap, // [x,y -> y,x]
+ add, // [x,y -> x+y]
+ sub, // [x,y -> x-y]
+ mul, // [x,y -> x*y]
+ div, // [x,y -> x/y]
+ mod, // [x,y -> x%y]
+ create, // [value -> ] Creates binding this.name in the top scope
+ store, // [value -> ] Stores in the first scope to contain a this.name binding
+ load, // [ -> value] Retrieves from the first scope to contain a this.name binding
+ enter, // [scope -> ] Pushes the given scope on the scope stack
+ leave, // [ -> ] Pops from the scope stack
+ call, // [scope,arg,...,arg -> scope] Pops this.nargs arguments and replaces for names from scope.scopeDef.args
+ };
+
+ Type type;
+ double num;
+ string str;
+ ScopeDef *scope;
+ string name;
+ int nargs;
+
+ Instruction(Type type);
+ Instruction(Type type,double num); // pushnum
+ Instruction(Type type,const string &str); // pushstr, create, store, load
+ Instruction(Type type,ScopeDef *scope); // pushscope
+ Instruction(Type type,int nargs); // call
+ };
+
+ vector<Instruction> listing;
+
+ void codegen(const StatementList &stl);
+ void codegen(const Statement &stmt);
+ void codegen(const Expression &expr);
+
+public:
+ Assembly(const StatementList &stl);
+
+ friend ostream& operator<<(ostream &os,const Assembly &as);
+};
+
+ostream& operator<<(ostream &os,const Assembly &as);
+
+
+class Context{
+ vector<ScopeVal> sstack;
+
+public:
+ void evaluate(const Assembly &as);
+};