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);
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:
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);
#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"
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);
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:
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;
#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"
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);
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);
}
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;
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)
if(s->type == SYM) {
free(s->value.s);
}
+ if(s->type == STR) {
+ free(s->value.str);
+ }
free(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;
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;
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;
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);
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();
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 {
Sexpr_Type type;
union {
K_UINT_TYPE u;
+ char* str;
Builtin_t b;
Symbol_t s;
Cons_t* c;