basic hello world
This commit is contained in:
parent
abd7bcda7f
commit
ad67aa9ac5
36
src/Scope.cpp
Normal file
36
src/Scope.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "Scope.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
bool Scope::varExists(Context& ctx, std::string name) {
|
||||||
|
if (vars.find(name) == vars.end()) {
|
||||||
|
if (parentScope.get() == nullptr) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return parentScope.get()->varExists(ctx, name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::any& Scope::getVar(Context& cxt, std::string name) {
|
||||||
|
if (vars.find(name) == vars.end()) {
|
||||||
|
if (varExists(cxt, name)) {
|
||||||
|
return parentScope.get()->getVar(cxt, name);
|
||||||
|
} else {
|
||||||
|
// doesn't exist at all
|
||||||
|
throw new std::exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vars.at(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scope::writeVar(Context& cxt, std::string name, std::any& var) {
|
||||||
|
if (vars.find(name) == vars.end()) {
|
||||||
|
if (varExists(cxt, name)) {
|
||||||
|
parentScope.get()->writeVar(cxt, name, var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vars.insert_or_assign(name, var);
|
||||||
|
}
|
31
src/Scope.h
Normal file
31
src/Scope.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <any>
|
||||||
|
|
||||||
|
class Context;
|
||||||
|
|
||||||
|
// Scope - parent scope, local variables, return handler, continue handler, break handler
|
||||||
|
class Scope {
|
||||||
|
public:
|
||||||
|
std::shared_ptr<Scope> parentScope;
|
||||||
|
std::unordered_map<std::string, std::any> vars;
|
||||||
|
// std::function<bool(Context&,Args&)> returnHandler;
|
||||||
|
// std::function<bool(Context&)> breakHandler;
|
||||||
|
// std::function<bool(Context&)> continueHandler;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Scope(std::shared_ptr<Scope> parentScope) : parentScope(parentScope) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool varExists(Context& ctx, std::string name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up var and creates it in the current scope if it doesn't exist
|
||||||
|
*/
|
||||||
|
std::any& getVar(Context& cxt, std::string name);
|
||||||
|
|
||||||
|
void writeVar(Context& cxt, std::string name, std::any& var);
|
||||||
|
};
|
7
src/context.cpp
Normal file
7
src/context.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void Context::error(std::string_view msg) {
|
||||||
|
std::cout << "Error! " << msg << std::endl;
|
||||||
|
}
|
16
src/context.h
Normal file
16
src/context.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "Scope.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
class Context {
|
||||||
|
public:
|
||||||
|
std::unordered_map<std::string_view, Func> builtins;
|
||||||
|
std::shared_ptr<Scope> currentScope;
|
||||||
|
public:
|
||||||
|
void error(std::string_view msg);
|
||||||
|
};
|
139
src/main.cpp
139
src/main.cpp
@ -2,7 +2,9 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <exception>
|
|
||||||
|
#include "context.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
using peg::SemanticValues;
|
using peg::SemanticValues;
|
||||||
using std::any_cast;
|
using std::any_cast;
|
||||||
@ -54,137 +56,6 @@ int main_old(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Func;
|
|
||||||
class Scope;
|
|
||||||
class Identifier;
|
|
||||||
|
|
||||||
// represents the 'nil' type
|
|
||||||
class Nil {
|
|
||||||
};
|
|
||||||
|
|
||||||
class Context {
|
|
||||||
public:
|
|
||||||
std::unordered_map<std::string_view, Func> builtins;
|
|
||||||
std::shared_ptr<Scope> currentScope;
|
|
||||||
public:
|
|
||||||
void error(std::string_view msg) {
|
|
||||||
std::cout << "Error! " << msg << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Identifier {
|
|
||||||
public:
|
|
||||||
std::string identifier;
|
|
||||||
Identifier(std::string id) : identifier(id) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// table, function, number, string
|
|
||||||
// enum Type {
|
|
||||||
// Type_Table,
|
|
||||||
// Type_Function,
|
|
||||||
// Type_Number,
|
|
||||||
// Type_String,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Scope - parent scope, local variables, return handler, continue handler, break handler
|
|
||||||
class Scope {
|
|
||||||
public:
|
|
||||||
std::shared_ptr<Scope> parentScope;
|
|
||||||
std::unordered_map<std::string_view, std::any&> vars;
|
|
||||||
// std::function<bool(Context&,Args&)> returnHandler;
|
|
||||||
// std::function<bool(Context&)> breakHandler;
|
|
||||||
// std::function<bool(Context&)> continueHandler;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Scope(std::shared_ptr<Scope> parentScope) : parentScope(parentScope) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool varExists(Context& ctx, std::string_view name) {
|
|
||||||
if (vars.find(name) == vars.end()) {
|
|
||||||
if (parentScope.get() == nullptr) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return parentScope.get()->varExists(ctx, name);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Looks up var and creates it in the current scope if it doesn't exist
|
|
||||||
*/
|
|
||||||
std::any& getVar(Context& cxt, std::string_view name) {
|
|
||||||
if (vars.find(name) == vars.end()) {
|
|
||||||
if (varExists(cxt, name)) {
|
|
||||||
return parentScope.get()->getVar(cxt, name);
|
|
||||||
} else {
|
|
||||||
// doesn't exist at all
|
|
||||||
throw new std::exception();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return vars.at(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeVar(Context& cxt, std::string_view name, std::any& var) {
|
|
||||||
if (vars.find(name) == vars.end()) {
|
|
||||||
if (varExists(cxt, name)) {
|
|
||||||
parentScope.get()->writeVar(cxt, name, var);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vars.insert_or_assign(name, var);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Arguments passed to a function and also results returned from a function
|
|
||||||
*/
|
|
||||||
class Args {
|
|
||||||
public:
|
|
||||||
std::vector<std::any> args;
|
|
||||||
static Args toArgs(Context& cxt, std::any input) {
|
|
||||||
Args args;
|
|
||||||
if (input.type() == typeid(Identifier)) {
|
|
||||||
auto id = any_cast<Identifier>(input);
|
|
||||||
auto value = cxt.currentScope->getVar(cxt, id.identifier);
|
|
||||||
args.args.push_back(value);
|
|
||||||
}
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Function - captured scope, ast ptr OR native function
|
|
||||||
class Func {
|
|
||||||
public:
|
|
||||||
std::shared_ptr<Scope> capturedScope;
|
|
||||||
// ast ptr
|
|
||||||
std::function<void(Context&,Args&)> nativeFunction;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Func(std::function<void(Context&,Args&)> nativeFunction)
|
|
||||||
: capturedScope(nullptr), nativeFunction(nativeFunction) {}
|
|
||||||
|
|
||||||
void execute(Context& cxt, Args& args) {
|
|
||||||
// TODO implement AST executer
|
|
||||||
nativeFunction(cxt, args);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class BuiltinFunctions {
|
|
||||||
public:
|
|
||||||
static void 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 << any_cast<long>(var) << '\t';
|
|
||||||
} else {
|
|
||||||
cxt.error("Attempt to print unsupported type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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") {
|
||||||
@ -198,7 +69,7 @@ std::any eval(Context &cxt, peg::Ast& ast) {
|
|||||||
cxt.currentScope->writeVar(cxt, identifier.identifier, value);
|
cxt.currentScope->writeVar(cxt, identifier.identifier, value);
|
||||||
return Nil();
|
return Nil();
|
||||||
} else if (ast.name == "IDENTIFIER" || ast.name == "BUILTINIDENTIFIER") {
|
} else if (ast.name == "IDENTIFIER" || ast.name == "BUILTINIDENTIFIER") {
|
||||||
return Identifier(ast.token_to_string());
|
return Identifier(std::string(ast.token_to_string()));
|
||||||
} else if (ast.name == "INTEGER") {
|
} else if (ast.name == "INTEGER") {
|
||||||
// TODO parse hex, oct, and binary
|
// TODO parse hex, oct, and binary
|
||||||
return ast.token_to_number<long>();
|
return ast.token_to_number<long>();
|
||||||
@ -206,6 +77,8 @@ std::any eval(Context &cxt, peg::Ast& ast) {
|
|||||||
auto identifier = any_cast<Identifier>(eval(cxt, *nodes[0]));
|
auto identifier = any_cast<Identifier>(eval(cxt, *nodes[0]));
|
||||||
auto args = Args::toArgs(cxt, eval(cxt, *nodes[1]));
|
auto args = Args::toArgs(cxt, eval(cxt, *nodes[1]));
|
||||||
cxt.builtins.at(identifier.identifier).execute(cxt, args);
|
cxt.builtins.at(identifier.identifier).execute(cxt, args);
|
||||||
|
// TODO: handle returns
|
||||||
|
return Nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "AST Name: " << ast.name << std::endl;
|
std::cout << "AST Name: " << ast.name << std::endl;
|
||||||
|
27
src/util.cpp
Normal file
27
src/util.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
void 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 {
|
||||||
|
cxt.error("Attempt to print unsupported type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
52
src/util.h
Normal file
52
src/util.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <any>
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class Context;
|
||||||
|
class Scope;
|
||||||
|
|
||||||
|
// represents the 'nil' type
|
||||||
|
class Nil {
|
||||||
|
};
|
||||||
|
|
||||||
|
class Identifier {
|
||||||
|
public:
|
||||||
|
std::string identifier;
|
||||||
|
Identifier(std::string id) : identifier(id) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arguments passed to a function and also results returned from a function
|
||||||
|
*/
|
||||||
|
class Args {
|
||||||
|
public:
|
||||||
|
std::vector<std::any> args;
|
||||||
|
static Args toArgs(Context& cxt, std::any input);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function - captured scope, ast ptr OR native function
|
||||||
|
class Func {
|
||||||
|
public:
|
||||||
|
std::shared_ptr<Scope> capturedScope;
|
||||||
|
// ast ptr
|
||||||
|
std::function<void(Context&,Args&)> nativeFunction;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Func(std::function<void(Context&,Args&)> nativeFunction)
|
||||||
|
: capturedScope(nullptr), nativeFunction(nativeFunction) {}
|
||||||
|
|
||||||
|
void execute(Context& cxt, Args& args) {
|
||||||
|
// TODO implement AST executer
|
||||||
|
nativeFunction(cxt, args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BuiltinFunctions {
|
||||||
|
public:
|
||||||
|
static void print(Context& cxt, Args& args);
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user