functions and stuff
This commit is contained in:
parent
4600c5f85a
commit
f2b4a53176
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
|
||||
project(dpro)
|
||||
project(dbuild)
|
||||
|
||||
set(THIRD_PARTY_INCLUDE_DIRS third_party)
|
||||
set(SRC_DIRS src)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{ pkgs ? import <nixpkgs> { } }:
|
||||
pkgs.stdenv.mkDerivation rec {
|
||||
pname = "dpro";
|
||||
pname = "dbuild";
|
||||
version = "0.1.0";
|
||||
|
||||
src = ./.;
|
||||
@ -20,6 +20,6 @@ pkgs.stdenv.mkDerivation rec {
|
||||
|
||||
installPhase = ''
|
||||
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) {
|
||||
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;
|
||||
public:
|
||||
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
|
||||
/ AssignExpr SEMICOLON
|
||||
|
||||
IfStatement
|
||||
<- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
|
||||
/ IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
|
||||
IfStatement <- IfPrefix Block ( KEYWORD_else Payload? Block )?
|
||||
|
||||
LabeledStatement <- BlockLabel? (Block / LoopStatement)
|
||||
|
||||
LoopStatement <- ForStatement / WhileStatement
|
||||
|
||||
ForStatement
|
||||
<- ForPrefix BlockExpr ( KEYWORD_else Statement )?
|
||||
/ ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement )
|
||||
ForStatement <- ForPrefix Block
|
||||
|
||||
WhileStatement
|
||||
<- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
|
||||
/ WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
|
||||
|
||||
BlockExpr <- BlockLabel? Block
|
||||
WhileStatement <- WhilePrefix Block
|
||||
|
||||
# *** Expression Level ***
|
||||
AssignExpr <- Expr (AssignOp Expr)?
|
||||
@ -71,8 +63,7 @@ ForExpr <- ForPrefix Expr (KEYWORD_else Expr)?
|
||||
|
||||
WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)?
|
||||
|
||||
SuffixExpr
|
||||
<- PrimaryTypeExpr (SuffixOp / FnCallArguments)*
|
||||
SuffixExpr <- PrimaryTypeExpr (SuffixOp / FnCallArguments)*
|
||||
|
||||
PrimaryTypeExpr
|
||||
<- BUILTINCALL
|
||||
@ -120,7 +111,6 @@ AssignOp
|
||||
/ AMPERSANDEQUAL
|
||||
/ CARETEQUAL
|
||||
/ PIPEEQUAL
|
||||
/ ASTERISKPERCENTEQUAL
|
||||
/ EQUAL
|
||||
|
||||
CompareOp
|
||||
@ -148,8 +138,6 @@ MultiplyOp
|
||||
<- ASTERISK
|
||||
/ SLASH
|
||||
/ PERCENT
|
||||
/ ASTERISK2
|
||||
/ ASTERISKPERCENT
|
||||
|
||||
PrefixOp
|
||||
<- EXCLAMATIONMARK
|
||||
@ -163,9 +151,9 @@ SuffixOp
|
||||
FnCallArguments <- LPAREN ExprList RPAREN
|
||||
|
||||
# Lists
|
||||
ExprList <- (Expr COMMA)* Expr?
|
||||
ExprList <- (Expr COMMA)* Expr? { no_ast_opt }
|
||||
|
||||
ParamDeclList <- (IDENTIFIER COMMA)* IDENTIFIER?
|
||||
ParamDeclList <- (IDENTIFIER COMMA)* IDENTIFIER? { no_ast_opt }
|
||||
|
||||
# *** Tokens ***
|
||||
INTEGER
|
||||
@ -253,10 +241,7 @@ STRINGLITERALSINGLE <- "\"" < string_char* > "\"" skip
|
||||
~AMPERSAND <- '&' ![=] skip
|
||||
~AMPERSANDEQUAL <- '&=' skip
|
||||
~ASTERISK <- '*' ![*%=] skip
|
||||
~ASTERISK2 <- '**' skip
|
||||
~ASTERISKEQUAL <- '*=' skip
|
||||
~ASTERISKPERCENT <- '*%' ![=] skip
|
||||
~ASTERISKPERCENTEQUAL <- '*%=' skip
|
||||
~CARET <- '^' ![=] skip
|
||||
~CARETEQUAL <- '^=' skip
|
||||
~COLON <- ':' skip
|
||||
|
155
src/main.cpp
155
src/main.cpp
@ -7,139 +7,6 @@
|
||||
#include "context.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) {
|
||||
peg::parser parser(
|
||||
#include "grammar.peg"
|
||||
@ -147,7 +14,27 @@ int main(void) {
|
||||
std::string s = R"(
|
||||
var a = "hello world";
|
||||
var b = 20 + 10 + 5 - 10 * 2 / 2;
|
||||
b *= 2;
|
||||
@print("hello world");
|
||||
@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();
|
||||
@ -166,7 +53,7 @@ int main(void) {
|
||||
cxt.builtins.emplace("print", Func(BuiltinFunctions::print));
|
||||
cxt.currentScope = scope;
|
||||
|
||||
eval(cxt, *ast);
|
||||
cxt.eval(*ast);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
32
src/util.cpp
32
src/util.cpp
@ -6,11 +6,7 @@
|
||||
|
||||
Args Args::toArgs(Context& cxt, std::any input) {
|
||||
Args args;
|
||||
if (input.type() == typeid(Identifier)) {
|
||||
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>)) {
|
||||
if (input.type() == typeid(std::vector<std::any>)) {
|
||||
args.args = std::any_cast<std::vector<std::any>>(input);
|
||||
} else {
|
||||
cxt.error("Unimplemented toArgs");
|
||||
@ -18,16 +14,40 @@ Args Args::toArgs(Context& cxt, std::any input) {
|
||||
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++) {
|
||||
std::any var = args.args[i];
|
||||
if (var.type() == typeid(long)) {
|
||||
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 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 {
|
||||
cxt.error("Attempt to print unsupported type");
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
return Nil();
|
||||
}
|
27
src/util.h
27
src/util.h
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cpp-peglib/peglib.h>
|
||||
|
||||
#include <string>
|
||||
#include <any>
|
||||
#include <vector>
|
||||
@ -33,20 +35,29 @@ public:
|
||||
class Func {
|
||||
public:
|
||||
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:
|
||||
Func(std::function<void(Context&,Args&)> nativeFunction)
|
||||
/**
|
||||
* Create a native function
|
||||
*/
|
||||
Func(std::function<std::any(Context&,Args&)> nativeFunction)
|
||||
: capturedScope(nullptr), nativeFunction(nativeFunction) {}
|
||||
|
||||
void execute(Context& cxt, Args& args) {
|
||||
// TODO implement AST executer
|
||||
nativeFunction(cxt, args);
|
||||
}
|
||||
/**
|
||||
* Create an interpreted function
|
||||
*/
|
||||
Func(std::shared_ptr<peg::Ast> ast, std::vector<Identifier> argNames)
|
||||
: ast(ast), argNames(argNames) {}
|
||||
|
||||
std::any execute(Context& cxt, Args& args);
|
||||
};
|
||||
|
||||
class BuiltinFunctions {
|
||||
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