aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2024-06-15 21:06:27 -0400
committerClyne Sullivan <clyne@bitgloo.com>2024-06-15 21:06:27 -0400
commit6be79eda61b3c64b38528c023845991a0cb4a274 (patch)
treeeb95a1980831b1e62641335ce1e7b7cbbfa9b044
parented78a6054c628e80240eff8ea9a06412774df094 (diff)
recursion; list via support.c
-rw-r--r--ast.cpp18
-rw-r--r--main.cpp6
-rw-r--r--support.c36
-rw-r--r--test.fp23
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<ThunkAST> 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<ThunkAST> scope;
+std::list<ThunkAST> 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 <stdio.h>
#include <stdint.h>
+#include <stdlib.h>
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
)