basic operators

This commit is contained in:
zuckerberg 2021-07-09 09:19:47 -06:00
parent ad67aa9ac5
commit 4600c5f85a
3 changed files with 62 additions and 4 deletions

View File

@ -187,7 +187,7 @@ FLOAT
STRINGLITERAL STRINGLITERAL
<- STRINGLITERALSINGLE <- STRINGLITERALSINGLE
/ (line_string skip)+ / (line_string skip)+
STRINGLITERALSINGLE <- "\"" string_char* "\"" skip STRINGLITERALSINGLE <- "\"" < string_char* > "\"" skip
~bin_int <- bin bin_* ~bin_int <- bin bin_*
~oct_int <- oct oct_* ~oct_int <- oct oct_*

View File

@ -1,6 +1,7 @@
#include <cpp-peglib/peglib.h> #include <cpp-peglib/peglib.h>
#include <assert.h> #include <assert.h>
#include <iostream> #include <iostream>
#include <cassert>
#include <unordered_map> #include <unordered_map>
#include "context.h" #include "context.h"
@ -56,6 +57,21 @@ int main_old(void) {
return 0; return 0;
} }
std::any readIdentifier(Context &cxt, std::any val) {
assert(val.type() == typeid(Identifier));
return cxt.currentScope->getVar(cxt, any_cast<Identifier>(val).identifier);
}
/**
* Returns the value of the input (reads the value if it is a refers to a variable)
*/
std::any getValue(Context& cxt, std::any input) {
if (input.type() == typeid(Identifier))
return readIdentifier(cxt, input);
else
return input;
}
std::any eval(Context &cxt, peg::Ast& ast) { std::any eval(Context &cxt, peg::Ast& ast) {
const auto &nodes = ast.nodes; const auto &nodes = ast.nodes;
if (ast.name == "Root") { if (ast.name == "Root") {
@ -79,6 +95,41 @@ std::any eval(Context &cxt, peg::Ast& ast) {
cxt.builtins.at(identifier.identifier).execute(cxt, args); cxt.builtins.at(identifier.identifier).execute(cxt, args);
// TODO: handle returns // TODO: handle returns
return Nil(); return Nil();
} else if (ast.name == "STRINGLITERALSINGLE")
{
return ast.token_to_string();
} else if (ast.name == "ExprList") {
std::vector<std::any> exprs;
for (int i=0; i<ast.nodes.size(); i++) {
exprs.push_back(getValue(cxt, eval(cxt, *nodes[i])));
}
return exprs;
} else if (ast.name == "AdditionExpr") {
auto value = getValue(cxt, eval(cxt, *nodes[0]));
for (int i=1; i<nodes.size(); i+=2) {
int op = (*nodes[i]).choice;
auto v2 = getValue(cxt, eval(cxt, *nodes[i+1]));
// TODO: floats
if (op == 0) {
value = any_cast<long>(value) + any_cast<long>(v2);
} else {
value = any_cast<long>(value) - any_cast<long>(v2);
}
}
return value;
} else if (ast.name == "MultiplyExpr") {
auto value = getValue(cxt, eval(cxt, *nodes[0]));
for (int i=1; i<nodes.size(); i+=2) {
int op = (*nodes[i]).choice;
auto v2 = getValue(cxt, eval(cxt, *nodes[i+1]));
// TODO: floats
if (op == 0) {
value = any_cast<long>(value) * any_cast<long>(v2);
} else {
value = any_cast<long>(value) / any_cast<long>(v2);
}
}
return value;
} }
std::cout << "AST Name: " << ast.name << std::endl; std::cout << "AST Name: " << ast.name << std::endl;
@ -94,8 +145,9 @@ int main(void) {
#include "grammar.peg" #include "grammar.peg"
); );
std::string s = R"( std::string s = R"(
var a = 10; var a = "hello world";
@print(a); var b = 20 + 10 + 5 - 10 * 2 / 2;
@print(a,b);
)"; )";
parser.enable_ast(); parser.enable_ast();

View File

@ -10,6 +10,10 @@ Args Args::toArgs(Context& cxt, std::any input) {
auto id = std::any_cast<Identifier>(input); auto id = std::any_cast<Identifier>(input);
auto value = cxt.currentScope->getVar(cxt, id.identifier); auto value = cxt.currentScope->getVar(cxt, id.identifier);
args.args.push_back(value); args.args.push_back(value);
} else if (input.type() == typeid(std::vector<std::any>)) {
args.args = std::any_cast<std::vector<std::any>>(input);
} else {
cxt.error("Unimplemented toArgs");
} }
return args; return args;
} }
@ -17,8 +21,10 @@ Args Args::toArgs(Context& cxt, std::any input) {
void BuiltinFunctions::print(Context& cxt, Args& args) { void BuiltinFunctions::print(Context& cxt, Args& args) {
for (int i=0; i<args.args.size(); i++) { for (int i=0; i<args.args.size(); i++) {
std::any var = args.args[i]; std::any var = args.args[i];
if ( var.type() == typeid(long) ) { if (var.type() == typeid(long)) {
std::cout << std::any_cast<long>(var) << '\t'; std::cout << std::any_cast<long>(var) << '\t';
} else if (var.type() == typeid(std::string)) {
std::cout << std::any_cast<std::string>(var) << '\t';
} else { } else {
cxt.error("Attempt to print unsupported type"); cxt.error("Attempt to print unsupported type");
} }