This commit is contained in:
zuckerberg 2021-07-13 19:10:27 -04:00
parent 70cecced8d
commit 4ace3f049d
6 changed files with 224 additions and 103 deletions

View File

@ -28,40 +28,40 @@ Value Context::eval(peg::Ast& ast) {
for (int i=0; i<ast.nodes.size(); i++) {
eval(*nodes[i]);
}
return Nil();
return Value(cxt, Nil());
} else if (ast.name == "VarDecl") {
std::string identifier = eval(*nodes[0]).getIdentifier(cxt).identifier;
Value value = eval(*nodes[1]);
currentScope->writeVar(cxt, identifier, value);
return Nil();
return Value(cxt, Nil());
} else if (ast.name == "IDENTIFIER" || ast.name == "BUILTINIDENTIFIER") {
return Identifier(std::string(ast.token_to_string()));
return Value(cxt, Identifier(std::string(ast.token_to_string())));
} else if (ast.name == "INTEGER") {
// TODO parse hex, oct, and binary
return ast.token_to_number<long>();
return Value(cxt, ast.token_to_number<long>());
} else if (ast.name == "FLOAT") {
return Value(cxt, ast.token_to_number<double>());
} else if (ast.name == "BUILTINCALL" ) {
std::string identifier = eval(*nodes[0]).getIdentifier(cxt).identifier;
Args args = eval(*nodes[1]).getArgs(cxt);
return builtins.at(identifier).execute(cxt, args);
} else if (ast.name == "STRINGLITERALSINGLE")
{
return ast.token_to_string();
return Value(cxt, ast.token_to_string());
} else if (ast.name == "ExprList") {
Args exprs;
for (int i=0; i<ast.nodes.size(); i++) {
exprs.args.push_back(getValue(eval(*nodes[i])));
}
return exprs;
return Value(cxt, exprs);
} else if (ast.name == "AdditionExpr") {
Value value = getValue(eval(*nodes[0]));
for (int i=1; i<nodes.size(); i+=2) {
int op = (*nodes[i]).choice;
Value v2 = getValue(eval(*nodes[i+1]));
// TODO: floats
if (op == 0) {
value = value.getInt(cxt) + v2.getInt(cxt);
value = value + v2;
} else {
value = value.getInt(cxt) - v2.getInt(cxt);
value = value - v2;
}
}
return value;
@ -70,11 +70,10 @@ Value Context::eval(peg::Ast& ast) {
for (int i=1; i<nodes.size(); i+=2) {
int op = (*nodes[i]).choice;
Value v2 = getValue(eval(*nodes[i+1]));
// TODO: floats
if (op == 0) {
value = value.getInt(cxt) * v2.getInt(cxt);
value = value * v2;
} else {
value = value.getInt(cxt) / v2.getInt(cxt);
value = value / v2;
}
}
return value;
@ -84,22 +83,21 @@ Value Context::eval(peg::Ast& ast) {
auto v1 = currentScope->getVar(*this, name);
int op = (*nodes[1]).choice;
auto v2 = getValue(eval(*nodes[2]));
Value result = Nil();
// TODO: floats
Value result = Value(cxt, Nil());
if (op == 0) {
result = v1.getInt(cxt) * v2.getInt(cxt);
result = v1 * v2;
} else if (op == 1) {
result = v1.getInt(cxt) % v2.getInt(cxt);
result = v1 % v2;
} else if (op == 2) {
result = v1.getInt(cxt) + v2.getInt(cxt);
result = v1 + v2;
} else if (op == 3) {
result = v1.getInt(cxt) - v2.getInt(cxt);
result = v1 - v2;
} else if (op == 4) {
result = v1.getInt(cxt) & v2.getInt(cxt);
result = v1 & v2;
} else if (op == 5) {
result = v1.getInt(cxt) ^ v2.getInt(cxt);
result = v1 ^ v2;
} else if (op == 6) {
result = v1.getInt(cxt) | v2.getInt(cxt);
result = v1 | v2;
} else if (op == 7) {
result = v2;
}
@ -107,12 +105,12 @@ Value Context::eval(peg::Ast& ast) {
return result;
} else if (ast.name == "PrimaryTypeExpr") {
int op = ast.choice;
if (op == 8) {
return false;
if (op == 7) {
return Value(cxt, false);
} else if (op == 8) {
return Value(cxt, Nil());
} else if (op == 9) {
return Nil();
} else if (op == 10) {
return true;
return Value(cxt, true);
}
} else if (ast.name == "CompareExpr") {
Value v1 = getValue(eval(*nodes[0]));
@ -120,17 +118,17 @@ Value Context::eval(peg::Ast& ast) {
Value v2 = getValue(eval(*nodes[2]));
// TODO: floats, bool, etc.
if (op == 0) {
return (bool)(v1.getInt(cxt) == v2.getInt(cxt));
return v1 == v2;
} else if (op == 1) {
return (bool)(v1.getInt(cxt) != v2.getInt(cxt));
return v1 != v2;
} else if (op == 2) {
return (bool)(v1.getInt(cxt) < v2.getInt(cxt));
return v1 < v2;
} else if (op == 3) {
return (bool)(v1.getInt(cxt) > v2.getInt(cxt));
return v1 > v2;
} else if (op == 4) {
return (bool)(v1.getInt(cxt) <= v2.getInt(cxt));
return v1 <= v2;
} else if (op == 5) {
return (bool)(v1.getInt(cxt) >= v2.getInt(cxt));
return v1 >= v2;
}
} else if (ast.name == "IfStatement") {
Value val = getValue(eval(*nodes[0]));
@ -141,13 +139,13 @@ Value Context::eval(peg::Ast& ast) {
}
} else if (ast.name == "Block") {
// TODO create new scope
Value result = Nil();
Value result = Value(cxt, Nil());
for (int i=0; i<ast.nodes.size(); i++) {
result = eval(*nodes[i]);
}
return result;
} else if (ast.name == "WhileStatement") {
Value result = Nil();
Value result = Value(cxt, Nil());
while (getValue(eval(*nodes[0])).getBoolean(cxt)) {
result = eval(*nodes[1]);
}
@ -158,13 +156,13 @@ Value Context::eval(peg::Ast& ast) {
for (int i=0; i<args.args.size(); i++) {
identifiers.push_back(args.args[i].getIdentifier(cxt));
}
return Func(nodes[1], identifiers);
return Value(cxt, Func(nodes[1], identifiers));
} else if (ast.name == "ParamDeclList") {
Args identifiers;
for (int i=0; i<nodes.size(); i++) {
identifiers.args.push_back(Value(eval(*nodes[i]).getIdentifier(cxt)));
identifiers.args.push_back(Value(cxt, eval(*nodes[i]).getIdentifier(cxt)));
}
return identifiers;
return Value(cxt, identifiers);
} else if (ast.name == "SuffixExpr") {
// TODO handle other PrimaryTypeExpr types
Value val = getValue(eval(*nodes[0]));
@ -180,5 +178,5 @@ Value Context::eval(peg::Ast& ast) {
std::cout << "AST child: " << ast.name << " : ";
eval(*nodes[i]);
}
return Nil();
return Value(cxt, Nil());
}

View File

@ -67,7 +67,6 @@ SuffixExpr <- PrimaryTypeExpr (SuffixOp / FnCallArguments)*
PrimaryTypeExpr
<- BUILTINCALL
/ CHAR_LITERAL
/ DOT IDENTIFIER
/ FLOAT
/ Fn
@ -156,21 +155,14 @@ ExprList <- (Expr COMMA)* Expr? { no_ast_opt }
ParamDeclList <- (IDENTIFIER COMMA)* IDENTIFIER? { no_ast_opt }
# *** Tokens ***
INTEGER
<- "0b" < bin_int > skip
/ "0o" < oct_int > skip
/ "0x" < hex_int > skip
/ < dec_int > skip
INTEGER <- < dec_int > skip
IDENTIFIER <- !keyword < [A-Za-z_] [A-Za-z0-9_]* > skip
BUILTINIDENTIFIER <- "@" < [A-Za-z_][A-Za-z0-9_]* > skip
CHAR_LITERAL <- "'" char_char "'" skip
FLOAT
<- "0x" hex_int "." hex_int ([pP] [-+]? dec_int)? skip
/ dec_int "." dec_int ([eE] [-+]? dec_int)? skip
/ "0x" hex_int "."? [pP] [-+]? dec_int skip
/ dec_int "."? [eE] [-+]? dec_int skip
<- < dec_int "." dec_int ([eE] [-+]? dec_int)? > skip
/ < dec_int "."? [eE] [-+]? dec_int > skip
STRINGLITERAL
<- STRINGLITERALSINGLE

View File

@ -35,6 +35,8 @@ int main(void) {
@print(abc);
};
hello("world");
a = 0.1 / 100;
@print(a);
)";
parser.enable_ast();

View File

@ -7,7 +7,7 @@ Value Func::execute(Context& cxt, Args& args) {
return nativeFunction(cxt, args);
} else {
// TODO create scope
Value result = Value(Nil());
Value result = Value(cxt, Nil());
for (int i=0; i<args.args.size(); i++) {
cxt.currentScope->writeVar(cxt, argNames[i].identifier, args.args[i]);
}
@ -17,32 +17,32 @@ Value Func::execute(Context& cxt, Args& args) {
}
}
Value::Value(Nil nil) : type(TypeNil) {
Value::Value(Context &cxt, Nil nil) : cxt(cxt), type(TypeNil) {
value.nil = Nil();
}
Value::Value(long int_) : type(TypeInt) {
Value::Value(Context &cxt, long int_) : cxt(cxt), type(TypeInt) {
value.int_ = int_;
}
Value::Value(double float_) : type(TypeFloat) {
Value::Value(Context &cxt, double float_) : cxt(cxt), type(TypeFloat) {
value.float_ = float_;
}
Value::Value(bool bool_) : type(TypeBoolean) {
Value::Value(Context &cxt, bool bool_) : cxt(cxt), type(TypeBoolean) {
value.bool_ = bool_;
}
Value::Value(const std::string &string) : type(TypeString) {
Value::Value(Context &cxt, const std::string &string) : cxt(cxt), type(TypeString) {
value.string = new std::string(string);
}
Value::Value(const Func &function) : type(TypeFunction) {
Value::Value(Context &cxt, const Func &function) : cxt(cxt), type(TypeFunction) {
value.function = new Func(function);
}
Value::Value(const Args &args) : type(TypeArgs) {
Value::Value(Context &cxt, const Args &args) : cxt(cxt), type(TypeArgs) {
value.args = new Args(args);
}
Value::Value(const Identifier &identifier) : type(TypeIdentifier) {
Value::Value(Context &cxt, const Identifier &identifier) : cxt(cxt), type(TypeIdentifier) {
value.identifier = new Identifier(identifier);
}
Value::Value(const Value &val) {
Value::Value(const Value &val) : cxt(val.cxt) {
if (val.isNil()) {
*this = Nil();
} else if (val.isInt()) {
@ -178,87 +178,198 @@ bool Value::isIdentifier() const {
return type == TypeIdentifier;
}
void Value::assertNil(Context &cxt) {
void Value::assertNil(Context &cxt) const {
if (!isNil()) {
cxt.error("value is not nil");
}
}
void Value::assertInt(Context &cxt) {
void Value::assertInt(Context &cxt) const {
if (!isInt()) {
cxt.error("value is not an integer");
}
}
void Value::assertFloat(Context &cxt) {
void Value::assertFloat(Context &cxt) const {
if (!isFloat()) {
cxt.error("value is not a float");
}
}
void Value::assertNumber(Context &cxt) {
void Value::assertNumber(Context &cxt) const {
if (!isNumber()) {
cxt.error("value is not a number");
}
}
void Value::assertBoolean(Context &cxt) {
void Value::assertBoolean(Context &cxt) const {
if (!isBoolean()) {
cxt.error("value is not a boolean");
}
}
void Value::assertString(Context &cxt) {
void Value::assertString(Context &cxt) const {
if (!isString()) {
cxt.error("value is not a string");
}
}
void Value::assertFunction(Context &cxt) {
void Value::assertFunction(Context &cxt) const {
if (!isFunction()) {
cxt.error("value is not a function");
}
}
void Value::assertArgs(Context &cxt) {
void Value::assertArgs(Context &cxt) const {
if (!isArgs()) {
cxt.error("value is not arguments");
}
}
void Value::assertIdentifier(Context &cxt) {
void Value::assertIdentifier(Context &cxt) const {
if (!isIdentifier()) {
cxt.error("value is not identifier");
}
}
Nil Value::getNil(Context &cxt) {
Nil Value::getNil(Context &cxt) const {
assertNil(cxt);
return value.nil;
}
long Value::getInt(Context &cxt) {
long Value::getInt(Context &cxt) const {
assertNumber(cxt);
if (isFloat())
return (long)value.float_;
else
return value.int_;
}
double Value::getFloat(Context &cxt) {
double Value::getFloat(Context &cxt) const {
assertNumber(cxt);
if (isInt())
return (double)value.int_;
else
return value.float_;
}
bool Value::getBoolean(Context &cxt) {
bool Value::getBoolean(Context &cxt) const {
assertBoolean(cxt);
return value.bool_;
}
std::string Value::getString(Context &cxt) {
std::string Value::getString(Context &cxt) const {
assertString(cxt);
return *value.string;
}
Func Value::getFunction(Context &cxt) {
Func Value::getFunction(Context &cxt) const {
assertFunction(cxt);
return *value.function;
}
Args Value::getArgs(Context &cxt) {
Args Value::getArgs(Context &cxt) const {
assertArgs(cxt);
return *value.args;
}
Identifier Value::getIdentifier(Context &cxt) {
Identifier Value::getIdentifier(Context &cxt) const {
assertIdentifier(cxt);
return *value.identifier;
}
Value Value::operator+(const Value &rhs) const {
assertNumber(cxt);
rhs.assertNumber(cxt);
if (isFloat() || rhs.isFloat()) {
return Value(cxt, getFloat(cxt) + rhs.getFloat(cxt));
} else {
return Value(cxt, getInt(cxt) + rhs.getInt(cxt));
}
}
Value Value::operator-(const Value &rhs) const {
assertNumber(cxt);
rhs.assertNumber(cxt);
if (isFloat() || rhs.isFloat()) {
return Value(cxt, getFloat(cxt) - rhs.getFloat(cxt));
} else {
return Value(cxt, getInt(cxt) - rhs.getInt(cxt));
}
}
Value Value::operator*(const Value &rhs) const {
assertNumber(cxt);
rhs.assertNumber(cxt);
if (isFloat() || rhs.isFloat()) {
return Value(cxt, getFloat(cxt) * rhs.getFloat(cxt));
} else {
return Value(cxt, getInt(cxt) * rhs.getInt(cxt));
}
}
Value Value::operator/(const Value &rhs) const {
assertNumber(cxt);
rhs.assertNumber(cxt);
if (isFloat() || rhs.isFloat()) {
return Value(cxt, getFloat(cxt) / rhs.getFloat(cxt));
} else {
return Value(cxt, getInt(cxt) / rhs.getInt(cxt));
}
}
Value Value::operator%(const Value &rhs) const {
assertInt(cxt);
rhs.assertInt(cxt);
return Value(cxt, getInt(cxt) % rhs.getInt(cxt));
}
Value Value::operator&(const Value &rhs) const {
assertInt(cxt);
rhs.assertInt(cxt);
return Value(cxt, getInt(cxt) & rhs.getInt(cxt));
}
Value Value::operator^(const Value &rhs) const {
assertInt(cxt);
rhs.assertInt(cxt);
return Value(cxt, getInt(cxt) ^ rhs.getInt(cxt));
}
Value Value::operator|(const Value &rhs) const {
assertInt(cxt);
rhs.assertInt(cxt);
return Value(cxt, getInt(cxt) | rhs.getInt(cxt));
}
Value Value::operator==(const Value &rhs) const {
assertNumber(cxt);
rhs.assertNumber(cxt);
if (isFloat() || rhs.isFloat()) {
return Value(cxt, getFloat(cxt) == rhs.getFloat(cxt));
} else {
return Value(cxt, getInt(cxt) == rhs.getInt(cxt));
}
}
Value Value::operator!=(const Value &rhs) const {
assertNumber(cxt);
rhs.assertNumber(cxt);
if (isFloat() || rhs.isFloat()) {
return Value(cxt, getFloat(cxt) != rhs.getFloat(cxt));
} else {
return Value(cxt, getInt(cxt) != rhs.getInt(cxt));
}
}
Value Value::operator<(const Value &rhs) const {
assertNumber(cxt);
rhs.assertNumber(cxt);
if (isFloat() || rhs.isFloat()) {
return Value(cxt, getFloat(cxt) < rhs.getFloat(cxt));
} else {
return Value(cxt, getInt(cxt) < rhs.getInt(cxt));
}
}
Value Value::operator>(const Value &rhs) const {
assertNumber(cxt);
rhs.assertNumber(cxt);
if (isFloat() || rhs.isFloat()) {
return Value(cxt, getFloat(cxt) > rhs.getFloat(cxt));
} else {
return Value(cxt, getInt(cxt) > rhs.getInt(cxt));
}
}
Value Value::operator<=(const Value &rhs) const {
assertNumber(cxt);
rhs.assertNumber(cxt);
if (isFloat() || rhs.isFloat()) {
return Value(cxt, getFloat(cxt) <= rhs.getFloat(cxt));
} else {
return Value(cxt, getInt(cxt) <= rhs.getInt(cxt));
}
}
Value Value::operator>=(const Value &rhs) const {
assertNumber(cxt);
rhs.assertNumber(cxt);
if (isFloat() || rhs.isFloat()) {
return Value(cxt, getFloat(cxt) >= rhs.getFloat(cxt));
} else {
return Value(cxt, getInt(cxt) >= rhs.getInt(cxt));
}
}

View File

@ -81,16 +81,17 @@ protected:
Type type = TypeNil;
TypeValues value;
Context &cxt;
public:
Value(Nil nil);
Value(long int_);
Value(double float_);
Value(bool bool_);
Value(const std::string &string);
Value(const Func &function);
Value(const Args &args);
Value(const Identifier &identifier);
Value(Context &cxt, Nil nil);
Value(Context &cxt, long int_);
Value(Context &cxt, double float_);
Value(Context &cxt, bool bool_);
Value(Context &cxt, const std::string &string);
Value(Context &cxt, const Func &function);
Value(Context &cxt, const Args &args);
Value(Context &cxt, const Identifier &identifier);
Value(const Value &value);
Value& operator=(const Value &rhs);
@ -117,22 +118,37 @@ public:
bool isArgs() const;
bool isIdentifier() const;
void assertNil(Context &cxt);
void assertInt(Context &cxt);
void assertFloat(Context &cxt);
void assertNumber(Context &cxt);
void assertBoolean(Context &cxt);
void assertString(Context &cxt);
void assertFunction(Context &cxt);
void assertArgs(Context &cxt);
void assertIdentifier(Context &cxt);
void assertNil(Context &cxt) const;
void assertInt(Context &cxt) const;
void assertFloat(Context &cxt) const;
void assertNumber(Context &cxt) const;
void assertBoolean(Context &cxt) const;
void assertString(Context &cxt) const;
void assertFunction(Context &cxt) const;
void assertArgs(Context &cxt) const;
void assertIdentifier(Context &cxt) const;
Nil getNil(Context &cxt);
long getInt(Context &cxt);
double getFloat(Context &cxt);
bool getBoolean(Context &cxt);
std::string getString(Context &cxt);
Func getFunction(Context &cxt);
Args getArgs(Context &cxt);
Identifier getIdentifier(Context &cxt);
Nil getNil(Context &cxt) const;
long getInt(Context &cxt) const;
double getFloat(Context &cxt) const;
bool getBoolean(Context &cxt) const;
std::string getString(Context &cxt) const;
Func getFunction(Context &cxt) const;
Args getArgs(Context &cxt) const;
Identifier getIdentifier(Context &cxt) const;
Value operator+(const Value &rhs) const;
Value operator-(const Value &rhs) const;
Value operator*(const Value &rhs) const;
Value operator/(const Value &rhs) const;
Value operator%(const Value &rhs) const;
Value operator&(const Value &rhs) const;
Value operator^(const Value &rhs) const;
Value operator|(const Value &rhs) const;
Value operator==(const Value &rhs) const;
Value operator!=(const Value &rhs) const;
Value operator<(const Value &rhs) const;
Value operator>(const Value &rhs) const;
Value operator<=(const Value &rhs) const;
Value operator>=(const Value &rhs) const;
};

View File

@ -20,10 +20,12 @@ Value BuiltinFunctions::print(Context& cxt, Args& args) {
std::cout << "false" << '\t';
} else if (var.isNil()) {
std::cout << "nil" << '\t';
} else if (var.isFloat()) {
std::cout << var.getFloat(cxt) << std::endl;
} else {
cxt.error("Attempt to print unsupported type");
}
}
std::cout << std::endl;
return Nil();
return Value(cxt, Nil());
}