functions and stuff
This commit is contained in:
parent
4600c5f85a
commit
f2b4a53176
@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.7)
|
cmake_minimum_required(VERSION 3.7)
|
||||||
|
|
||||||
project(dpro)
|
project(dbuild)
|
||||||
|
|
||||||
set(THIRD_PARTY_INCLUDE_DIRS third_party)
|
set(THIRD_PARTY_INCLUDE_DIRS third_party)
|
||||||
set(SRC_DIRS src)
|
set(SRC_DIRS src)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ pkgs ? import <nixpkgs> { } }:
|
{ pkgs ? import <nixpkgs> { } }:
|
||||||
pkgs.stdenv.mkDerivation rec {
|
pkgs.stdenv.mkDerivation rec {
|
||||||
pname = "dpro";
|
pname = "dbuild";
|
||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
|
|
||||||
src = ./.;
|
src = ./.;
|
||||||
@ -20,6 +20,6 @@ pkgs.stdenv.mkDerivation rec {
|
|||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
mv dpro $out/bin
|
mv dbuild $out/bin
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
176
src/context.cpp
176
src/context.cpp
@ -4,4 +4,180 @@
|
|||||||
|
|
||||||
void Context::error(std::string_view msg) {
|
void Context::error(std::string_view msg) {
|
||||||
std::cout << "Error! " << msg << std::endl;
|
std::cout << "Error! " << msg << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
using std::any_cast;
|
||||||
|
|
||||||
|
std::any Context::readIdentifier(std::any val) {
|
||||||
|
assert(val.type() == typeid(Identifier));
|
||||||
|
return currentScope->getVar(*this, any_cast<Identifier>(val).identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the input (reads the value if it is a refers to a variable)
|
||||||
|
*/
|
||||||
|
std::any Context::getValue(std::any input) {
|
||||||
|
if (input.type() == typeid(Identifier))
|
||||||
|
return readIdentifier(input);
|
||||||
|
else
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::any Context::eval(peg::Ast& ast) {
|
||||||
|
const auto &nodes = ast.nodes;
|
||||||
|
if (ast.name == "Root") {
|
||||||
|
for (int i=0; i<ast.nodes.size(); i++) {
|
||||||
|
eval(*nodes[i]);
|
||||||
|
}
|
||||||
|
return Nil();
|
||||||
|
} else if (ast.name == "VarDecl") {
|
||||||
|
auto identifier = any_cast<Identifier>(eval(*nodes[0]));
|
||||||
|
auto value = eval(*nodes[1]);
|
||||||
|
currentScope->writeVar(*this, identifier.identifier, value);
|
||||||
|
return Nil();
|
||||||
|
} else if (ast.name == "IDENTIFIER" || ast.name == "BUILTINIDENTIFIER") {
|
||||||
|
return Identifier(std::string(ast.token_to_string()));
|
||||||
|
} else if (ast.name == "INTEGER") {
|
||||||
|
// TODO parse hex, oct, and binary
|
||||||
|
return ast.token_to_number<long>();
|
||||||
|
} else if (ast.name == "BUILTINCALL" ) {
|
||||||
|
auto identifier = any_cast<Identifier>(eval(*nodes[0]));
|
||||||
|
auto args = Args::toArgs(*this, eval(*nodes[1]));
|
||||||
|
builtins.at(identifier.identifier).execute(*this, args);
|
||||||
|
// TODO: handle returns
|
||||||
|
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(eval(*nodes[i])));
|
||||||
|
}
|
||||||
|
return exprs;
|
||||||
|
} else if (ast.name == "AdditionExpr") {
|
||||||
|
auto value = getValue(eval(*nodes[0]));
|
||||||
|
for (int i=1; i<nodes.size(); i+=2) {
|
||||||
|
int op = (*nodes[i]).choice;
|
||||||
|
auto v2 = getValue(eval(*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(eval(*nodes[0]));
|
||||||
|
for (int i=1; i<nodes.size(); i+=2) {
|
||||||
|
int op = (*nodes[i]).choice;
|
||||||
|
auto v2 = getValue(eval(*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 == "AssignExpr") {
|
||||||
|
std::string name = any_cast<Identifier>(eval(*nodes[0])).identifier;
|
||||||
|
// TODO arrays, dot operator, etc.
|
||||||
|
auto v1 = currentScope->getVar(*this, name);
|
||||||
|
int op = (*nodes[1]).choice;
|
||||||
|
auto v2 = getValue(eval(*nodes[2]));
|
||||||
|
std::any result;
|
||||||
|
// TODO: floats
|
||||||
|
if (op == 0) {
|
||||||
|
result = any_cast<long>(v1) * any_cast<long>(v2);
|
||||||
|
} else if (op == 1) {
|
||||||
|
result = any_cast<long>(v1) % any_cast<long>(v2);
|
||||||
|
} else if (op == 2) {
|
||||||
|
result = any_cast<long>(v1) + any_cast<long>(v2);
|
||||||
|
} else if (op == 3) {
|
||||||
|
result = any_cast<long>(v1) - any_cast<long>(v2);
|
||||||
|
} else if (op == 4) {
|
||||||
|
result = any_cast<long>(v1) & any_cast<long>(v2);
|
||||||
|
} else if (op == 5) {
|
||||||
|
result = any_cast<long>(v1) ^ any_cast<long>(v2);
|
||||||
|
} else if (op == 6) {
|
||||||
|
result = any_cast<long>(v1) | any_cast<long>(v2);
|
||||||
|
} else if (op == 7) {
|
||||||
|
result = v2;
|
||||||
|
}
|
||||||
|
currentScope->writeVar(*this, name, result);
|
||||||
|
return result;
|
||||||
|
} else if (ast.name == "PrimaryTypeExpr") {
|
||||||
|
int op = ast.choice;
|
||||||
|
if (op == 8) {
|
||||||
|
return false;
|
||||||
|
} else if (op == 9) {
|
||||||
|
return Nil();
|
||||||
|
} else if (op == 10) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (ast.name == "CompareExpr") {
|
||||||
|
auto v1 = getValue(eval(*nodes[0]));
|
||||||
|
int op = (*nodes[1]).choice;
|
||||||
|
auto v2 = getValue(eval(*nodes[2]));
|
||||||
|
// TODO: floats, bool, etc.
|
||||||
|
if (op == 0) {
|
||||||
|
return (bool)(any_cast<long>(v1) == any_cast<long>(v2));
|
||||||
|
} else if (op == 1) {
|
||||||
|
return (bool)(any_cast<long>(v1) != any_cast<long>(v2));
|
||||||
|
} else if (op == 2) {
|
||||||
|
return (bool)(any_cast<long>(v1) < any_cast<long>(v2));
|
||||||
|
} else if (op == 3) {
|
||||||
|
return (bool)(any_cast<long>(v1) > any_cast<long>(v2));
|
||||||
|
} else if (op == 4) {
|
||||||
|
return (bool)(any_cast<long>(v1) <= any_cast<long>(v2));
|
||||||
|
} else if (op == 5) {
|
||||||
|
return (bool)(any_cast<long>(v1) >= any_cast<long>(v2));
|
||||||
|
}
|
||||||
|
} else if (ast.name == "IfStatement") {
|
||||||
|
auto val = getValue(eval(*nodes[0]));
|
||||||
|
if (any_cast<bool>(val)) {
|
||||||
|
return eval(*nodes[1]);
|
||||||
|
} else {
|
||||||
|
return eval(*nodes[2]);
|
||||||
|
}
|
||||||
|
} else if (ast.name == "Block") {
|
||||||
|
// TODO create new scope
|
||||||
|
std::any result = Nil();
|
||||||
|
for (int i=0; i<ast.nodes.size(); i++) {
|
||||||
|
result = eval(*nodes[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else if (ast.name == "WhileStatement") {
|
||||||
|
std::any result = Nil();
|
||||||
|
while (any_cast<bool>(getValue(eval(*nodes[0])))) {
|
||||||
|
result = eval(*nodes[1]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else if (ast.name == "Fn") {
|
||||||
|
auto identifiers = any_cast<std::vector<Identifier>>(eval(*nodes[0]));
|
||||||
|
return Func(nodes[1], identifiers);
|
||||||
|
} else if (ast.name == "ParamDeclList") {
|
||||||
|
std::vector<Identifier> identifiers;
|
||||||
|
for (int i=0; i<nodes.size(); i++) {
|
||||||
|
identifiers.push_back(any_cast<Identifier>(eval(*nodes[i])));
|
||||||
|
}
|
||||||
|
return identifiers;
|
||||||
|
} else if (ast.name == "SuffixExpr") {
|
||||||
|
// TODO handle other PrimaryTypeExpr types
|
||||||
|
auto val = getValue(eval(*nodes[0]));
|
||||||
|
auto func = any_cast<Func>(val);
|
||||||
|
for (int i=1; i<nodes.size(); i++) {
|
||||||
|
auto args = Args::toArgs(*this, eval(*nodes[i]));
|
||||||
|
return func.execute(*this, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "AST Name: " << ast.name << std::endl;
|
||||||
|
for (int i=0; i<ast.nodes.size(); i++) {
|
||||||
|
std::cout << "AST child: " << ast.name << " : ";
|
||||||
|
eval(*nodes[i]);
|
||||||
|
}
|
||||||
|
return Nil();
|
||||||
}
|
}
|
@ -13,4 +13,8 @@ public:
|
|||||||
std::shared_ptr<Scope> currentScope;
|
std::shared_ptr<Scope> currentScope;
|
||||||
public:
|
public:
|
||||||
void error(std::string_view msg);
|
void error(std::string_view msg);
|
||||||
|
std::any eval(peg::Ast& ast);
|
||||||
|
protected:
|
||||||
|
std::any readIdentifier(std::any val);
|
||||||
|
std::any getValue(std::any input);
|
||||||
};
|
};
|
@ -13,23 +13,15 @@ Statement
|
|||||||
/ LabeledStatement
|
/ LabeledStatement
|
||||||
/ AssignExpr SEMICOLON
|
/ AssignExpr SEMICOLON
|
||||||
|
|
||||||
IfStatement
|
IfStatement <- IfPrefix Block ( KEYWORD_else Payload? Block )?
|
||||||
<- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
|
|
||||||
/ IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
|
|
||||||
|
|
||||||
LabeledStatement <- BlockLabel? (Block / LoopStatement)
|
LabeledStatement <- BlockLabel? (Block / LoopStatement)
|
||||||
|
|
||||||
LoopStatement <- ForStatement / WhileStatement
|
LoopStatement <- ForStatement / WhileStatement
|
||||||
|
|
||||||
ForStatement
|
ForStatement <- ForPrefix Block
|
||||||
<- ForPrefix BlockExpr ( KEYWORD_else Statement )?
|
|
||||||
/ ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement )
|
|
||||||
|
|
||||||
WhileStatement
|
WhileStatement <- WhilePrefix Block
|
||||||
<- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
|
|
||||||
/ WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
|
|
||||||
|
|
||||||
BlockExpr <- BlockLabel? Block
|
|
||||||
|
|
||||||
# *** Expression Level ***
|
# *** Expression Level ***
|
||||||
AssignExpr <- Expr (AssignOp Expr)?
|
AssignExpr <- Expr (AssignOp Expr)?
|
||||||
@ -71,8 +63,7 @@ ForExpr <- ForPrefix Expr (KEYWORD_else Expr)?
|
|||||||
|
|
||||||
WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)?
|
WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)?
|
||||||
|
|
||||||
SuffixExpr
|
SuffixExpr <- PrimaryTypeExpr (SuffixOp / FnCallArguments)*
|
||||||
<- PrimaryTypeExpr (SuffixOp / FnCallArguments)*
|
|
||||||
|
|
||||||
PrimaryTypeExpr
|
PrimaryTypeExpr
|
||||||
<- BUILTINCALL
|
<- BUILTINCALL
|
||||||
@ -120,7 +111,6 @@ AssignOp
|
|||||||
/ AMPERSANDEQUAL
|
/ AMPERSANDEQUAL
|
||||||
/ CARETEQUAL
|
/ CARETEQUAL
|
||||||
/ PIPEEQUAL
|
/ PIPEEQUAL
|
||||||
/ ASTERISKPERCENTEQUAL
|
|
||||||
/ EQUAL
|
/ EQUAL
|
||||||
|
|
||||||
CompareOp
|
CompareOp
|
||||||
@ -148,8 +138,6 @@ MultiplyOp
|
|||||||
<- ASTERISK
|
<- ASTERISK
|
||||||
/ SLASH
|
/ SLASH
|
||||||
/ PERCENT
|
/ PERCENT
|
||||||
/ ASTERISK2
|
|
||||||
/ ASTERISKPERCENT
|
|
||||||
|
|
||||||
PrefixOp
|
PrefixOp
|
||||||
<- EXCLAMATIONMARK
|
<- EXCLAMATIONMARK
|
||||||
@ -163,9 +151,9 @@ SuffixOp
|
|||||||
FnCallArguments <- LPAREN ExprList RPAREN
|
FnCallArguments <- LPAREN ExprList RPAREN
|
||||||
|
|
||||||
# Lists
|
# Lists
|
||||||
ExprList <- (Expr COMMA)* Expr?
|
ExprList <- (Expr COMMA)* Expr? { no_ast_opt }
|
||||||
|
|
||||||
ParamDeclList <- (IDENTIFIER COMMA)* IDENTIFIER?
|
ParamDeclList <- (IDENTIFIER COMMA)* IDENTIFIER? { no_ast_opt }
|
||||||
|
|
||||||
# *** Tokens ***
|
# *** Tokens ***
|
||||||
INTEGER
|
INTEGER
|
||||||
@ -253,10 +241,7 @@ STRINGLITERALSINGLE <- "\"" < string_char* > "\"" skip
|
|||||||
~AMPERSAND <- '&' ![=] skip
|
~AMPERSAND <- '&' ![=] skip
|
||||||
~AMPERSANDEQUAL <- '&=' skip
|
~AMPERSANDEQUAL <- '&=' skip
|
||||||
~ASTERISK <- '*' ![*%=] skip
|
~ASTERISK <- '*' ![*%=] skip
|
||||||
~ASTERISK2 <- '**' skip
|
|
||||||
~ASTERISKEQUAL <- '*=' skip
|
~ASTERISKEQUAL <- '*=' skip
|
||||||
~ASTERISKPERCENT <- '*%' ![=] skip
|
|
||||||
~ASTERISKPERCENTEQUAL <- '*%=' skip
|
|
||||||
~CARET <- '^' ![=] skip
|
~CARET <- '^' ![=] skip
|
||||||
~CARETEQUAL <- '^=' skip
|
~CARETEQUAL <- '^=' skip
|
||||||
~COLON <- ':' skip
|
~COLON <- ':' skip
|
||||||
|
155
src/main.cpp
155
src/main.cpp
@ -7,139 +7,6 @@
|
|||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
using peg::SemanticValues;
|
|
||||||
using std::any_cast;
|
|
||||||
|
|
||||||
int main_old(void) {
|
|
||||||
// (2) Make a parser
|
|
||||||
peg::parser parser(R"(
|
|
||||||
# Grammar for Calculator...
|
|
||||||
Additive <- Multitive '+' Additive / Multitive
|
|
||||||
Multitive <- Primary '*' Multitive / Primary
|
|
||||||
Primary <- '(' Additive ')' / Number
|
|
||||||
Number <- < [0-9]+ >
|
|
||||||
%whitespace <- [ \t]*
|
|
||||||
)");
|
|
||||||
|
|
||||||
assert(static_cast<bool>(parser) == true);
|
|
||||||
|
|
||||||
// (3) Setup actions
|
|
||||||
parser["Additive"] = [](const SemanticValues &vs) {
|
|
||||||
switch (vs.choice()) {
|
|
||||||
case 0: // "Multitive '+' Additive"
|
|
||||||
return any_cast<int>(vs[0]) + any_cast<int>(vs[1]);
|
|
||||||
default: // "Multitive"
|
|
||||||
return any_cast<int>(vs[0]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
parser["Multitive"] = [](const SemanticValues &vs) {
|
|
||||||
switch (vs.choice()) {
|
|
||||||
case 0: // "Primary '*' Multitive"
|
|
||||||
return any_cast<int>(vs[0]) * any_cast<int>(vs[1]);
|
|
||||||
default: // "Primary"
|
|
||||||
return any_cast<int>(vs[0]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
parser["Number"] = [](const SemanticValues &vs) {
|
|
||||||
return vs.token_to_number<int>();
|
|
||||||
};
|
|
||||||
|
|
||||||
// (4) Parse
|
|
||||||
parser.enable_packrat_parsing(); // Enable packrat parsing.
|
|
||||||
|
|
||||||
int val;
|
|
||||||
parser.parse(" (1 + 2) * 3 ", val);
|
|
||||||
|
|
||||||
assert(val == 9);
|
|
||||||
|
|
||||||
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) {
|
|
||||||
const auto &nodes = ast.nodes;
|
|
||||||
if (ast.name == "Root") {
|
|
||||||
for (int i=0; i<ast.nodes.size(); i++) {
|
|
||||||
eval(cxt, *nodes[i]);
|
|
||||||
}
|
|
||||||
return Nil();
|
|
||||||
} else if (ast.name == "VarDecl") {
|
|
||||||
auto identifier = any_cast<Identifier>(eval(cxt, *nodes[0]));
|
|
||||||
auto value = eval(cxt, *nodes[1]);
|
|
||||||
cxt.currentScope->writeVar(cxt, identifier.identifier, value);
|
|
||||||
return Nil();
|
|
||||||
} else if (ast.name == "IDENTIFIER" || ast.name == "BUILTINIDENTIFIER") {
|
|
||||||
return Identifier(std::string(ast.token_to_string()));
|
|
||||||
} else if (ast.name == "INTEGER") {
|
|
||||||
// TODO parse hex, oct, and binary
|
|
||||||
return ast.token_to_number<long>();
|
|
||||||
} else if (ast.name == "BUILTINCALL" ) {
|
|
||||||
auto identifier = any_cast<Identifier>(eval(cxt, *nodes[0]));
|
|
||||||
auto args = Args::toArgs(cxt, eval(cxt, *nodes[1]));
|
|
||||||
cxt.builtins.at(identifier.identifier).execute(cxt, args);
|
|
||||||
// TODO: handle returns
|
|
||||||
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;
|
|
||||||
for (int i=0; i<ast.nodes.size(); i++) {
|
|
||||||
std::cout << "AST child: " << ast.name << " : ";
|
|
||||||
eval(cxt, *nodes[i]);
|
|
||||||
}
|
|
||||||
return Nil();
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
peg::parser parser(
|
peg::parser parser(
|
||||||
#include "grammar.peg"
|
#include "grammar.peg"
|
||||||
@ -147,7 +14,27 @@ int main(void) {
|
|||||||
std::string s = R"(
|
std::string s = R"(
|
||||||
var a = "hello world";
|
var a = "hello world";
|
||||||
var b = 20 + 10 + 5 - 10 * 2 / 2;
|
var b = 20 + 10 + 5 - 10 * 2 / 2;
|
||||||
|
b *= 2;
|
||||||
|
@print("hello world");
|
||||||
@print(a,b);
|
@print(a,b);
|
||||||
|
b = 2;
|
||||||
|
@print(b);
|
||||||
|
a = b != 2;
|
||||||
|
@print(a);
|
||||||
|
if (a) {
|
||||||
|
@print("yay");
|
||||||
|
} else {
|
||||||
|
@print("neigh");
|
||||||
|
}
|
||||||
|
a = 10;
|
||||||
|
while(a > 0) {
|
||||||
|
a -= 1;
|
||||||
|
@print(a);
|
||||||
|
}
|
||||||
|
var hello = fn(abc) {
|
||||||
|
@print(abc);
|
||||||
|
};
|
||||||
|
hello("world");
|
||||||
)";
|
)";
|
||||||
|
|
||||||
parser.enable_ast();
|
parser.enable_ast();
|
||||||
@ -166,7 +53,7 @@ int main(void) {
|
|||||||
cxt.builtins.emplace("print", Func(BuiltinFunctions::print));
|
cxt.builtins.emplace("print", Func(BuiltinFunctions::print));
|
||||||
cxt.currentScope = scope;
|
cxt.currentScope = scope;
|
||||||
|
|
||||||
eval(cxt, *ast);
|
cxt.eval(*ast);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
32
src/util.cpp
32
src/util.cpp
@ -6,11 +6,7 @@
|
|||||||
|
|
||||||
Args Args::toArgs(Context& cxt, std::any input) {
|
Args Args::toArgs(Context& cxt, std::any input) {
|
||||||
Args args;
|
Args args;
|
||||||
if (input.type() == typeid(Identifier)) {
|
if (input.type() == typeid(std::vector<std::any>)) {
|
||||||
auto id = std::any_cast<Identifier>(input);
|
|
||||||
auto value = cxt.currentScope->getVar(cxt, id.identifier);
|
|
||||||
args.args.push_back(value);
|
|
||||||
} else if (input.type() == typeid(std::vector<std::any>)) {
|
|
||||||
args.args = std::any_cast<std::vector<std::any>>(input);
|
args.args = std::any_cast<std::vector<std::any>>(input);
|
||||||
} else {
|
} else {
|
||||||
cxt.error("Unimplemented toArgs");
|
cxt.error("Unimplemented toArgs");
|
||||||
@ -18,16 +14,40 @@ Args Args::toArgs(Context& cxt, std::any input) {
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuiltinFunctions::print(Context& cxt, Args& args) {
|
std::any Func::execute(Context& cxt, Args& args) {
|
||||||
|
if (ast == nullptr) {
|
||||||
|
return nativeFunction(cxt, args);
|
||||||
|
} else {
|
||||||
|
// TODO create scope
|
||||||
|
std::any result;
|
||||||
|
for (int i=0; i<args.args.size(); i++) {
|
||||||
|
cxt.currentScope->writeVar(cxt, argNames[i].identifier, args.args[i]);
|
||||||
|
}
|
||||||
|
result = cxt.eval(*ast);
|
||||||
|
// TODO tear down scope
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::any 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)) {
|
} else if (var.type() == typeid(std::string)) {
|
||||||
std::cout << std::any_cast<std::string>(var) << '\t';
|
std::cout << std::any_cast<std::string>(var) << '\t';
|
||||||
|
} else if (var.type() == typeid(bool)) {
|
||||||
|
bool v = std::any_cast<bool>(var);
|
||||||
|
if (v)
|
||||||
|
std::cout << "true" << '\t';
|
||||||
|
else
|
||||||
|
std::cout << "false" << '\t';
|
||||||
|
} else if (var.type() == typeid(Nil)) {
|
||||||
|
std::cout << "nil" << '\t';
|
||||||
} else {
|
} else {
|
||||||
cxt.error("Attempt to print unsupported type");
|
cxt.error("Attempt to print unsupported type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
return Nil();
|
||||||
}
|
}
|
27
src/util.h
27
src/util.h
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cpp-peglib/peglib.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <any>
|
#include <any>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -33,20 +35,29 @@ public:
|
|||||||
class Func {
|
class Func {
|
||||||
public:
|
public:
|
||||||
std::shared_ptr<Scope> capturedScope;
|
std::shared_ptr<Scope> capturedScope;
|
||||||
// ast ptr
|
|
||||||
std::function<void(Context&,Args&)> nativeFunction;
|
std::shared_ptr<peg::Ast> ast = nullptr;
|
||||||
|
std::vector<Identifier> argNames;
|
||||||
|
|
||||||
|
std::function<std::any(Context&,Args&)> nativeFunction;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Func(std::function<void(Context&,Args&)> nativeFunction)
|
/**
|
||||||
|
* Create a native function
|
||||||
|
*/
|
||||||
|
Func(std::function<std::any(Context&,Args&)> nativeFunction)
|
||||||
: capturedScope(nullptr), nativeFunction(nativeFunction) {}
|
: capturedScope(nullptr), nativeFunction(nativeFunction) {}
|
||||||
|
|
||||||
void execute(Context& cxt, Args& args) {
|
/**
|
||||||
// TODO implement AST executer
|
* Create an interpreted function
|
||||||
nativeFunction(cxt, args);
|
*/
|
||||||
}
|
Func(std::shared_ptr<peg::Ast> ast, std::vector<Identifier> argNames)
|
||||||
|
: ast(ast), argNames(argNames) {}
|
||||||
|
|
||||||
|
std::any execute(Context& cxt, Args& args);
|
||||||
};
|
};
|
||||||
|
|
||||||
class BuiltinFunctions {
|
class BuiltinFunctions {
|
||||||
public:
|
public:
|
||||||
static void print(Context& cxt, Args& args);
|
static std::any print(Context& cxt, Args& args);
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user