From 6be79eda61b3c64b38528c023845991a0cb4a274 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sat, 15 Jun 2024 21:06:27 -0400 Subject: [PATCH] recursion; list via support.c --- ast.cpp | 18 +++++++++++++----- main.cpp | 6 ++++-- support.c | 36 ++++++++++++++++++++++++++++++++++++ test.fp | 23 +++++++++++++++-------- 4 files changed, 68 insertions(+), 15 deletions(-) diff --git a/ast.cpp b/ast.cpp index 3543ee1..a528cc3 100644 --- a/ast.cpp +++ b/ast.cpp @@ -58,12 +58,20 @@ PopAST::PopAST(const std::string& n): BaseAST(n) {} llvm::Value *PopAST::codegen(LLVMState& llvmState) const { - auto gep = llvmState.createPop(); - auto var = llvmState.createVariable(name); - auto load = llvmState.builder.CreateLoad(llvmState.inttype, gep); - llvmState.builder.CreateStore(load, var, false); + if (name == "self") { + extern std::list scope; + auto func = scope.back().func; + auto var = llvmState.createVariable(name); + llvmState.builder.CreateStore(func, var, false); + return Var::addLocal(name, var).value; + } else { + auto gep = llvmState.createPop(); + auto var = llvmState.createVariable(name); + auto load = llvmState.builder.CreateLoad(llvmState.inttype, gep); + llvmState.builder.CreateStore(load, var, false); - return Var::addLocal(name, var).value; + return Var::addLocal(name, var).value; + } } CallAST::CallAST(const std::string& n): BaseAST(n) {} diff --git a/main.cpp b/main.cpp index a632c9b..19b76fe 100644 --- a/main.cpp +++ b/main.cpp @@ -31,7 +31,7 @@ #include "var.hpp" static LLVMState llvmState; -static std::list scope; +std::list scope; static bool parseString(std::string_view sv); @@ -42,8 +42,10 @@ int main() std::string line; for (unsigned lineno = 1; std::cin.good(); ++lineno) { std::getline(std::cin, line); - if (!parseString(line)) + if (!parseString(line)) { std::cerr << " at line " << lineno << std::endl; + return -1; + } } llvmState.output(); diff --git a/support.c b/support.c index cc0304f..44a39e4 100644 --- a/support.c +++ b/support.c @@ -1,5 +1,6 @@ #include #include +#include extern int32_t sp; extern int32_t stack; @@ -9,6 +10,11 @@ void emit() putchar(*(&stack + --sp)); } +void print() +{ + printf("%d\n", *(&stack + --sp)); +} + void sub() { int32_t *st = &stack; @@ -33,3 +39,33 @@ void eq() --sp; st[sp - 1] = st[sp - 1] == st[sp]; } + +void cons() +{ + int32_t *st = &stack; + int32_t *pair = malloc(2 * sizeof(int32_t)); + --sp; + pair[0] = st[sp]; + pair[1] = st[sp - 1]; + st[sp - 1] = (int32_t)pair; +} + +void car() +{ + int32_t *st = &stack; + st[sp - 1] = ((int32_t *)st[sp - 1])[0]; +} + +void cdr() +{ + int32_t *st = &stack; + st[sp - 1] = ((int32_t *)st[sp - 1])[1]; +} + +void decons() +{ + int32_t *st = &stack; + --sp; + free((int32_t *)st[sp]); +} + diff --git a/test.fp b/test.fp index 015f2ee..498a3eb 100644 --- a/test.fp +++ b/test.fp @@ -10,20 +10,27 @@ (nil eq) $null? ($x x) $force (10 emit) $cr - - ; recursion via y-combinator - ($f ($x (^x x) f) dup force) $Y ($g (^g Y)) $rec + (dup car swap cdr) $carcdr ; if-stmt ($c $t $f c ^f ^t rot cswap $_ force) $if ($f $t $c $fn ^f ^t ^c fn) $endif ; range - ($self $body $start $end - ^if (^start ^end eq) nil - (^start body ^end ^start 1 + ^body self) + ($self $start $end + ^if (^start ^end eq) + ^nil + (^start ^end ^start 1 + self swap cons) + endif + ) $range + + ($self $func $list + ^if (^list null?) + nil + (^list carcdr swap func ^func self) endif - ) rec $do + ) $foreach - 70 65 ^emit do cr + 58 48 range + ^emit foreach cr )