From 9db341eac57c04d7a922a6ecd922dcb71bdf9ba5 Mon Sep 17 00:00:00 2001 From: Inventor Xtreme Date: Mon, 13 Apr 2026 23:00:16 -0400 Subject: [PATCH] first commit --- Makefile | 50 +++++++ src/main.cpp | 365 ++++++++++++++++++++++++++++++++++++++++++++++++ src/testc.c | 5 + src/testc.h | 6 + src/testcpp.cpp | 7 + src/testcpp.hpp | 6 + 6 files changed, 439 insertions(+) create mode 100644 Makefile create mode 100644 src/main.cpp create mode 100644 src/testc.c create mode 100644 src/testc.h create mode 100644 src/testcpp.cpp create mode 100644 src/testcpp.hpp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..aef1076 --- /dev/null +++ b/Makefile @@ -0,0 +1,50 @@ +CC = gcc +CXX = g++ + +CPPFLAGS = -std=c++20 -g -Wall -Wextra -Wpedantic #-O3 -ffast-math +CFLAGS = -g -Wall -Wextra -Wpedantic #-O3 -ffast-math +LDFLAGS = -g -Wall -Wextra -Wpedantic #-O3 -ffast-math +LDLIBS = + + +SRC_DIR = src +OBJ_DIR = obj +BIN_DIR = bin + + + +EXE = $(BIN_DIR)/main + +C_SRC := $(wildcard $(SRC_DIR)/*.c) #GET LIST OF ALL C FILES +CPP_SRC := $(wildcard $(SRC_DIR)/*.cpp) #GET LIST OF ALL CPP FILES + +#SRC := $(C_SRC) $(CPP_SCR) + + +C_OBJ := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(C_SRC)) #MAKE LIST OF ALL C OBJECT FILES THAT NEED TO BE BUILT +CPP_OBJ := $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(CPP_SRC)) #MAKE LIST OF ALL CPP OBJECT FILES THAT NEED TO BE BUILT + +OBJ := $(C_OBJ) $(CPP_OBJ) + + +all: $(EXE) + +$(EXE): $(OBJ) | $(BIN_DIR) + $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@ + +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR) + $(CC) $(CFLAGS) -c $< -o $@ + + +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ + +$(BIN_DIR) $(OBJ_DIR): + mkdir -p $@ + + +clean: + @$(RM) -rv $(BIN_DIR) $(OBJ_DIR) + +.PHONY: all clean + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d39e306 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,365 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct Data { + virtual ~Data() {} +}; + +struct SelfEval : Data { + virtual ~SelfEval() {} +}; + +struct Applyable : Data { + virtual ~Applyable() {} +}; + +struct Cell { + Data *d; + size_t cdr = 0; +}; + +struct Env { + std::unordered_set builtin; + std::unordered_map userdef; +}; + +struct Symbol : Data{ + std::string data; + std::string Get() { + return data; + } +}; + +struct String : SelfEval { + std::string data; + std::string Get() { + return data; + } +}; + +struct Number : SelfEval { + int data; + int Get() { + return data; + } +}; + +struct Fork : Data { + size_t data; + size_t Get() { + return data; + } +}; + +struct Lambda : Data { + Env env; + Cell args; + Cell f; +}; + +struct Registers { + std::variant A; + std::variant B; + std::variant C; + Env E; +}; + +struct Machine { + size_t maxCells; + size_t freepos = 1; + std::vector mem; + + std::vector stack; + + Registers reg; + + Machine(size_t max) : mem(max) { + maxCells = max; + reg.E.builtin.insert("+"); + reg.E.builtin.insert("-"); + reg.E.builtin.insert("lambda"); + reg.E.builtin.insert("set"); + } + + size_t Apply(Data * d, size_t cdr) { + if (Symbol * fname = dynamic_cast(d)) { + if (reg.E.builtin.contains(fname->data)) { + return ApplyBuiltin(fname->data, cdr); + } else { //defined symbol. + return 0; //TODO + } + + } else if (Lambda * f = dynamic_cast(d)) { + reg.A = f->args; + reg.A = ((Fork *) (std::get(reg.A)).d)->data; + + reg.B = cdr; + auto tmp = reg.E; + //reg.E = f->env; + reg.E.userdef.merge(f->env.userdef); + while (std::get(reg.A) != 0) { + reg.E.userdef[ ((Symbol *) mem[std::get(reg.A)].d )->data] = std::get(reg.B); + reg.A = mem[std::get(reg.A)].cdr; + reg.B = mem[std::get(reg.B)].cdr; + } + + auto ret = Eval(f->f.d); + reg.E = tmp; + return newCell(ret); + + } else { + return 0; + } + } + + + size_t ApplyBuiltin(std::string fname, size_t cdr) { + if (fname == "+") { + int base = 0; + while (cdr != 0) { + Number *a = dynamic_cast(mem[cdr].d); + base += a->data; + cdr = mem[cdr].cdr; + } + Number *n = new Number; + n->data = base; + return newCell(n); + + } else if (fname == "-") { + Number *s = dynamic_cast(mem[cdr].d); + int base = s->data; + + cdr = mem[cdr].cdr; + if (cdr == 0) { + Number *n = new Number; + n->data = -base; + return newCell(n); + } else { + while (cdr != 0) { + Number *a = dynamic_cast(mem[cdr].d); + base -= a->data; + cdr = mem[cdr].cdr; + } + Number *n = new Number; + n->data = base; + return newCell(n); + } + } else if (fname == "lambda") { + Fork * args = dynamic_cast(mem[cdr].d); + Fork * f = dynamic_cast(mem[mem[cdr].cdr].d); + + Lambda * l = new Lambda; + l->env = reg.E; + l->args = mem[cdr]; //mem[args->data]; + l->f = mem[mem[cdr].cdr]; //mem[f->data]; + //std::cout <<"got lambd" << std::endl; + return newCell(l); + + } + return 0; + } + + size_t newCell() { + if (freepos >= maxCells) { + exit(1); + } + auto nc = freepos; + freepos += 1; + return nc; + } + + size_t newCell(Data *d) { + auto t = newCell(); + mem[t].d = d; + return t; + } + + Data *Eval(Data *d) { + // std::cout << "Eval top" << std::endl; + if (SelfEval *h = dynamic_cast(d)) { + return h; + } else if (Symbol *h = dynamic_cast(d)) { + if (reg.E.builtin.contains(h->data)) return h; + return mem[reg.E.userdef[h->data]].d; + } else if (Fork *h = dynamic_cast(d)) { + // std::cout << "Eval callllled" << std::endl; + // Symbol *car = dynamic_cast(mem[h->data].d); + //new car: + auto car = mem[h->data].d; + + // if (!car) { + // throw(100); + // } + size_t front = 0; + size_t current = 0; + size_t firstargleft = mem[h->data].cdr; + + // std::cout << "Farg " << firstargleft << std::endl; + + while (firstargleft != 0) { + if (auto c = dynamic_cast(car)) { + if(c->data == "lambda") { + front = mem[h->data].cdr; + break; + } + } + + if (front == 0) { + front = newCell(); + current = front; + } else { + auto temp = newCell(); + mem[current].cdr = temp; + current = temp; + } + + // std::cout << "here" << std::endl; + mem[current].d = Eval(mem[firstargleft].d); + + // std::cout << "there" << std::endl; + firstargleft = mem[firstargleft].cdr; + } + + return mem[Apply(Eval(car), front)].d; + } else { + throw("err"); + } + return NULL; + } + + void ListPrint(Cell c) { + while (true) { + if (typeid(*(c.d)) == typeid(Number)) { + auto p = dynamic_cast(c.d); + std::cout << p->Get() << " "; + } else if (typeid(*(c.d)) == typeid(Symbol)) { + auto p = dynamic_cast(c.d); + std::cout << p->Get() << " "; + } else if (typeid(*(c.d)) == typeid(String)) { + auto p = dynamic_cast(c.d); + std::cout << "@\"" << p->Get() << "\"@ "; + } else if (typeid(*(c.d)) == typeid(Fork)) { + std::cout << "("; + auto p = dynamic_cast(c.d); + ListPrint(mem[p->Get()]); + std::cout << ")"; + } + if (c.cdr == 0) + break; + c = mem[c.cdr]; + } + } + + Cell read_atom(std::istream &in) { + bool isnum = true; + + std::string pass = ""; + char ch; + + if (in.peek() == '"') { + in.get(ch); + while (true) { + in.get(ch); + if (ch == '\\') { + in.get(ch); + pass += ch; + } else if (ch == '"') { + break; + } else { + pass += ch; + } + } + Cell c; + c.cdr = 0; + auto n = new String; + n->data = pass; + c.d = n; + return c; + } + + while (in.get(ch) && ch != '(' && ch != ' ' && ch != ')') { + if (ch != '0' && ch != '1' && ch != '2' && ch != '3' && ch != '4' && ch != '5' && + ch != '6' && ch != '7' && ch != '8' && ch != '9') { + isnum = false; + } + pass += ch; + } + in.unget(); + + Cell c; + c.cdr = 0; + if (isnum) { + auto n = new Number; + n->data = std::stoi(pass); + c.d = n; + } else { + auto s = new Symbol; + s->data = pass; + c.d = s; + } + + return c; + } + + size_t read_expr(std::istream &in) { + size_t front = 0; + size_t current = 0; + + char ch; + while (in.get(ch)) { + if (!std::isspace(ch)) { + if (ch == '(') { + auto temp = newCell(); + mem[current].cdr = temp; + current = temp; + if (front == 0) { + front = current; + } + auto x = new Fork; + mem[current].d = x; + x->data = read_expr(in); + + } else if (ch == ')') { + break; + } else { + auto temp = newCell(); + mem[current].cdr = temp; + current = temp; + if (front == 0) { + front = current; + } + + in.unget(); + + mem[current] = read_atom(in); + } + } + } + + return front; + } +}; + +int main() { + auto m = Machine(1000); + + auto exp = m.read_expr(std::cin); + + m.ListPrint(m.mem[exp]); + std::cout << std::endl; + + Cell c; + c.d = m.Eval(m.mem[exp].d); + + m.ListPrint(c); + std::cout << std::endl; + + + return 0; +} diff --git a/src/testc.c b/src/testc.c new file mode 100644 index 0000000..8c780ff --- /dev/null +++ b/src/testc.c @@ -0,0 +1,5 @@ +#include + +void TestC() { + printf("TestC\n"); +} diff --git a/src/testc.h b/src/testc.h new file mode 100644 index 0000000..04350f8 --- /dev/null +++ b/src/testc.h @@ -0,0 +1,6 @@ +#ifndef TESTC_HEADER +#define TESTC_HEADER + +void TestC(); + +#endif diff --git a/src/testcpp.cpp b/src/testcpp.cpp new file mode 100644 index 0000000..8f7adc2 --- /dev/null +++ b/src/testcpp.cpp @@ -0,0 +1,7 @@ +#include + +using namespace std; +void TestCPPFunc() { + cout << "TestCPPFunc" << endl; + +} diff --git a/src/testcpp.hpp b/src/testcpp.hpp new file mode 100644 index 0000000..7d1dcb3 --- /dev/null +++ b/src/testcpp.hpp @@ -0,0 +1,6 @@ +#ifndef TESTCPP_HEADER +#define TESTCPP_HEADER + +void TestCPPFunc(); + +#endif