From 992ffcac1af4fbf3a56471d044cf3882af1cd343 Mon Sep 17 00:00:00 2001 From: Elijah Cohen Date: Wed, 30 Oct 2024 23:06:44 -0500 Subject: [PATCH] added strings with pretty much nothing to make them useful --- src/builtins/core.c | 36 +++++++++++++++++++++++++++++++++++ src/builtins/core.h | 3 +++ src/builtins/io.c | 17 +++++++++++++++++ src/builtins/io.h | 5 ++++- src/parser.c | 14 ++++++++++++++ src/sexpr.c | 31 ++++++++++++++++++++++++++++++ src/sexpr.h | 1 + src/test.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ src/types.h | 3 ++- 9 files changed, 154 insertions(+), 2 deletions(-) diff --git a/src/builtins/core.c b/src/builtins/core.c index 804c7cf..fdc1736 100644 --- a/src/builtins/core.c +++ b/src/builtins/core.c @@ -200,6 +200,39 @@ Sexpr* c_applyn(Sexpr* b, Sexpr* rest, Sexpr* env) { return cons(ret, rest); } +Sexpr* c_type(Sexpr* b, Sexpr* rest, Sexpr* env) { + // umm guess I gotta eval... + if(CORE_TYPE_ARGS != u64_get_num_args(b)) + return cons(b, rest); + Sexpr* args = b->value.b.args; + Sexpr* argev = eval(clone(car(args)), env); + Sexpr_Type t = argev->type; + sexpr_free(b); + sexpr_free(argev); + switch(t) { + case UINT: + return cons(from_string("uint"), rest); + case STR: + return cons(from_string("string"), rest); + case BUILTIN: + return cons(from_string("builtin"), rest); + case SYM: + return cons(from_string("symbol"), rest); + case CONS: + return cons(from_string("cons"), rest); + case NIL: + return cons(from_string("nil"), rest); + case T: + return cons(from_string("t"), rest); + case QUOTE: + return cons(from_string("quote"), rest); + case PTR: + return cons(from_string("pointer"), rest); + default: + return cons(from_string("unknown"), rest); + } +} + Sexpr* c_def(Sexpr* b, Sexpr* rest, Sexpr* env) { if(CORE_DEF_ARGS != u64_get_num_args(b)) return cons(b, rest); @@ -249,6 +282,8 @@ Sexpr* x_core_dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) { return c_unquote(b, rest, env); case CORE_APPLYN: return c_applyn(b, rest, env); + case CORE_TYPE: + return c_type(b, rest, env); case CORE_DEF: return c_def(b, rest, env); case CORE_EXIT: @@ -272,6 +307,7 @@ Sexpr* load_core_env(Sexpr* env) { load_builtin(CORE_REST_STR, (CORE_PREFIX << 8) | CORE_REST, env); load_builtin(CORE_UNQUOTE_STR, (CORE_PREFIX << 8) | CORE_UNQUOTE, env); + load_builtin(CORE_TYPE_STR, (CORE_PREFIX << 8) | CORE_TYPE, env); load_builtin(CORE_DEF_STR, (CORE_PREFIX << 8) | CORE_DEF, env); load_builtin(CORE_EXIT_STR, (CORE_PREFIX << 8) | CORE_EXIT, env); diff --git a/src/builtins/core.h b/src/builtins/core.h index 249d9f8..7ccc08e 100644 --- a/src/builtins/core.h +++ b/src/builtins/core.h @@ -42,6 +42,9 @@ #define CORE_APPLYN_ARGS 3 #define CORE_APPLYN_STR "applyn" +#define CORE_TYPE 0xfd +#define CORE_TYPE_ARGS 1 +#define CORE_TYPE_STR "type" #define CORE_DEF 0xfe // huh do i want this so close to exit? #define CORE_DEF_ARGS 2 #define CORE_DEF_STR "def" diff --git a/src/builtins/io.c b/src/builtins/io.c index 36178c7..1e54095 100644 --- a/src/builtins/io.c +++ b/src/builtins/io.c @@ -23,6 +23,20 @@ Sexpr* io_print(Sexpr* b, Sexpr* rest, Sexpr* env) { return cons(from_t(), rest); } +Sexpr* io_printstr(Sexpr* b, Sexpr* rest, Sexpr* env) { + if(IO_PRINTSTR_ARGS != u64_get_num_args(b)) { + return cons(b, rest); + } + Sexpr* arg = car(b->value.b.args); + if(arg->type != STR) { + sexpr_free(b); + return cons(from_nil(), rest); + } + PRINT(arg->value.str); + sexpr_free(b); + return cons(from_t(), rest); +} + Sexpr* io_print_b(Sexpr* b, Sexpr* rest, Sexpr* env) { if(IO_PB_ARGS != u64_get_num_args(b)) { return cons(b, rest); @@ -45,6 +59,8 @@ Sexpr* x_io_dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) { switch(code) { case IO_PRINT: return io_print(b, rest, env); + case IO_PRINTSTR: + return io_printstr(b, rest, env); case IO_PB: return io_print_b(b, rest, env); default: @@ -55,6 +71,7 @@ Sexpr* x_io_dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) { Sexpr* load_io_env(Sexpr* env) { load_builtin(IO_PRINT_STR, (IO_PREFIX << 8) | IO_PRINT, env); + load_builtin(IO_PRINTSTR_STR, (IO_PREFIX << 8) | IO_PRINTSTR, env); load_builtin(IO_PB_STR, (IO_PREFIX << 8) | IO_PB, env); return env; diff --git a/src/builtins/io.h b/src/builtins/io.h index 89fc7cc..7b805fe 100644 --- a/src/builtins/io.h +++ b/src/builtins/io.h @@ -8,7 +8,10 @@ #define IO_PRINT 0x00 #define IO_PRINT_ARGS 1 #define IO_PRINT_STR "print" -#define IO_PB 0x01 +#define IO_PRINTSTR 0x01 +#define IO_PRINTSTR_ARGS 1 +#define IO_PRINTSTR_STR "printstr" +#define IO_PB 0x02 #define IO_PB_ARGS 1 #define IO_PB_STR "pb" diff --git a/src/parser.c b/src/parser.c index ae709ec..c35f9c7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -41,6 +41,16 @@ Sexpr* tokenize(char* s) { already_in_sym = false; currlen = 0; } // close () + else if(*s == '"') { + if(!already_in_sym) { + // just mark the start, then iterate til close quote, then append? + // but what if uncompleted quote? + tok_start = s; + do {s++;} while(*s != '"' && *s != '\0'); + //s++; + tokens = append_fragment(tokens, tok_start, (s + 1 - tok_start)); + } + } else if(isspace(*s)) { if(already_in_sym) { tokens = append_fragment(tokens, tok_start, currlen); @@ -85,6 +95,10 @@ Sexpr* vals_parse(Sexpr* tokens) { sscanf(s, "%" K_UINT_SCAN, &u); next = from_uint(u); } + else if (*s == '"') { // issa string + s[strlen(s) - 1] = '\0'; // replaces close quote with + next = from_string(s + 1); + } else { next = from_sym(s); } diff --git a/src/sexpr.c b/src/sexpr.c index 1114ea0..b0843dd 100644 --- a/src/sexpr.c +++ b/src/sexpr.c @@ -32,6 +32,13 @@ Sexpr* from_sym(char* s) { return ret; } +Sexpr* from_string(char* s) { + Sexpr* ret = malloc(sizeof(Sexpr)); + ret->type = STR; + ret->value.str = strdup(s); + return ret; +} + Sexpr* from_uint(K_UINT_TYPE u) { Sexpr* ret = malloc(sizeof(Sexpr)); ret->type = UINT; @@ -99,6 +106,8 @@ Sexpr* equal(Sexpr* a, Sexpr* b) { return from_t(); if(t == SYM) return strcmp(a->value.s, b->value.s) == 0 ? from_t() : from_nil(); + if(t == STR) + return strcmp(a->value.str, b->value.str) == 0 ? from_t() : from_nil(); if(t == PTR) return (a->value.p == b->value.p) ? from_t() : from_nil(); if(t == UINT) @@ -134,6 +143,9 @@ void sexpr_free(Sexpr* s) { if(s->type == SYM) { free(s->value.s); } + if(s->type == STR) { + free(s->value.str); + } free(s); } @@ -146,6 +158,9 @@ Sexpr* clone(Sexpr* s) { case SYM: ret = from_sym(s->value.s); break; + case STR: + ret = from_string(s->value.str); + break; case PTR: ret = from_pointer(s->value.p); break; @@ -208,6 +223,14 @@ char* sprint_sexpr(Sexpr* s) { strcpy(out, s->value.s); return out; } + else if(s->type == STR) { + out = malloc(sizeof(char)*(strlen(s->value.str)+3)); + out[0] = '"'; + strcpy(out+1, s->value.str); + out[strlen(s->value.str) +1] = '"'; + out[strlen(s->value.str) + 2] = '\0'; + return out; + } else if(s->type == PTR) { out = strdup("<*>"); return out; @@ -285,6 +308,14 @@ char* sprint_sexpr_builtin(Sexpr* s) { strcpy(out, s->value.s); return out; } + else if(s->type == STR) { + out = malloc(sizeof(char)*(strlen(s->value.s)+3)); + out[0] = '"'; + strcpy(out+1, s->value.str); + out[strlen(s->value.str) + 1] = '"'; + out[strlen(s->value.str) + 2] = '\0'; + return out; + } else if(s->type == PTR) { out = strdup("<*>"); return out; diff --git a/src/sexpr.h b/src/sexpr.h index a3ff2cc..b67788a 100644 --- a/src/sexpr.h +++ b/src/sexpr.h @@ -6,6 +6,7 @@ Sexpr* from_nil(); Sexpr* from_t(); Sexpr* from_sym(char* s); +Sexpr* from_string(char* s); Sexpr* from_uint(uint64_t u); Sexpr* from_opcode(uint64_t u); Sexpr* from_quote(Sexpr* s); diff --git a/src/test.c b/src/test.c index 7e64cf1..672bc8e 100644 --- a/src/test.c +++ b/src/test.c @@ -348,7 +348,53 @@ void many_asserts() { sexpr_free(env); } +void test_string_parsing() { + printf("string parsing...\n"); + // okay, testing tokenize first... + //Sexpr* toks = tokenize("(a \"this\" 5 \"t e s t\" + \"srfij)tuij(ijorew\")"); + Sexpr* toks = tokenize("print \"this\" thing"); + char* out = sprint_sexpr(toks); + printf("toks 1: %s\n", out); + Sexpr* vals = vals_parse(toks); + out = sprint_sexpr(vals); + printf("vals 1: %s\n", out); + if(car(cdr(vals))->type == STR) { + printf("vuhuh\n"); + } + if(car(cdr(vals))->type == SYM) { + printf("vnuhuh\n"); + } + Sexpr* done = cons_parse(vals); + out = sprint_sexpr(done); + if(car(cdr(done))->type == STR) { + printf("uhuh\n"); + } + if(car(cdr(done))->type == SYM) { + printf("nuhuh\n"); + } + printf("done 1: %s\n", out); + printf("now testing for the weird bug\n"); + toks = tokenize("(a \"this\" 5 \"t e s t\" + \"srfij)tuij(ijorew\")"); + out = sprint_sexpr(toks); + printf("toks 2: %s\n", out); + toks = tokenize("(cons \"test\" \"idk\")"); + out = sprint_sexpr(toks); + printf("toks 3: %s\n", out); + toks = tokenize("(cons \"test\" \"idk\")"); + out = sprint_sexpr(toks); + printf("toks 4: %s\n", out); + toks = tokenize("(list \"hi\"\"hay\"\"huh\"\"heh\")"); + out = sprint_sexpr(toks); + printf("toks 5: %s\n", out); + vals = vals_parse(toks); + out = sprint_sexpr(vals); + printf("vals 5: %s\n", out); + + printf("string parsing done\n"); +} + void run_tests(){ + //test_string_parsing(); eval_tests(); many_asserts(); //memtest_eval(); diff --git a/src/types.h b/src/types.h index b48ba4c..eaff3ab 100644 --- a/src/types.h +++ b/src/types.h @@ -14,7 +14,7 @@ typedef void* Nil_t; typedef void* Truth_t; typedef enum Sexpr_Type { - UINT, SYM, BUILTIN, NIL, T, CONS, QUOTE, PTR + UINT, SYM, BUILTIN, NIL, T, CONS, QUOTE, PTR, STR } Sexpr_Type; typedef struct Cons { @@ -34,6 +34,7 @@ typedef struct Sexpr { Sexpr_Type type; union { K_UINT_TYPE u; + char* str; Builtin_t b; Symbol_t s; Cons_t* c; -- 2.39.2