first commit

This commit is contained in:
Inventor Xtreme 2026-04-13 23:00:16 -04:00
commit 9db341eac5
6 changed files with 439 additions and 0 deletions

50
Makefile Normal file
View file

@ -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

365
src/main.cpp Normal file
View file

@ -0,0 +1,365 @@
#include <cassert>
#include <iostream>
#include <istream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <variant>
#include <vector>
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<std::string> builtin;
std::unordered_map<std::string, size_t> 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<size_t, Data *, Cell> A;
std::variant<size_t, Data *, Cell> B;
std::variant<size_t, Data *, Cell> C;
Env E;
};
struct Machine {
size_t maxCells;
size_t freepos = 1;
std::vector<Cell> mem;
std::vector<Registers> 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<Symbol*>(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<Lambda*>(d)) {
reg.A = f->args;
reg.A = ((Fork *) (std::get<Cell>(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<size_t>(reg.A) != 0) {
reg.E.userdef[ ((Symbol *) mem[std::get<size_t>(reg.A)].d )->data] = std::get<size_t>(reg.B);
reg.A = mem[std::get<size_t>(reg.A)].cdr;
reg.B = mem[std::get<size_t>(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<Number *>(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<Number *>(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<Number *>(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<Fork*>(mem[cdr].d);
Fork * f = dynamic_cast<Fork*>(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<SelfEval *>(d)) {
return h;
} else if (Symbol *h = dynamic_cast<Symbol*>(d)) {
if (reg.E.builtin.contains(h->data)) return h;
return mem[reg.E.userdef[h->data]].d;
} else if (Fork *h = dynamic_cast<Fork *>(d)) {
// std::cout << "Eval callllled" << std::endl;
// Symbol *car = dynamic_cast<Symbol *>(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<Symbol*>(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<Number *>(c.d);
std::cout << p->Get() << " ";
} else if (typeid(*(c.d)) == typeid(Symbol)) {
auto p = dynamic_cast<Symbol *>(c.d);
std::cout << p->Get() << " ";
} else if (typeid(*(c.d)) == typeid(String)) {
auto p = dynamic_cast<String *>(c.d);
std::cout << "@\"" << p->Get() << "\"@ ";
} else if (typeid(*(c.d)) == typeid(Fork)) {
std::cout << "(";
auto p = dynamic_cast<Fork *>(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;
}

5
src/testc.c Normal file
View file

@ -0,0 +1,5 @@
#include <stdio.h>
void TestC() {
printf("TestC\n");
}

6
src/testc.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef TESTC_HEADER
#define TESTC_HEADER
void TestC();
#endif

7
src/testcpp.cpp Normal file
View file

@ -0,0 +1,7 @@
#include <iostream>
using namespace std;
void TestCPPFunc() {
cout << "TestCPPFunc" << endl;
}

6
src/testcpp.hpp Normal file
View file

@ -0,0 +1,6 @@
#ifndef TESTCPP_HEADER
#define TESTCPP_HEADER
void TestCPPFunc();
#endif