basic hello world

This commit is contained in:
zuckerberg 2021-07-09 07:14:49 -04:00
parent abd7bcda7f
commit ad67aa9ac5
7 changed files with 175 additions and 133 deletions

36
src/Scope.cpp Normal file
View 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
View 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
View 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
View 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);
};

View File

@ -2,7 +2,9 @@
#include <assert.h>
#include <iostream>
#include <unordered_map>
#include <exception>
#include "context.h"
#include "util.h"
using peg::SemanticValues;
using std::any_cast;
@ -54,137 +56,6 @@ int main_old(void) {
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) {
const auto &nodes = ast.nodes;
if (ast.name == "Root") {
@ -198,7 +69,7 @@ std::any eval(Context &cxt, peg::Ast& ast) {
cxt.currentScope->writeVar(cxt, identifier.identifier, value);
return Nil();
} 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") {
// TODO parse hex, oct, and binary
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 args = Args::toArgs(cxt, eval(cxt, *nodes[1]));
cxt.builtins.at(identifier.identifier).execute(cxt, args);
// TODO: handle returns
return Nil();
}
std::cout << "AST Name: " << ast.name << std::endl;

27
src/util.cpp Normal file
View 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
View 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);
};