the hito embeddable programming language
at main 126 lines 5.4 kB view raw
1#include "bitset.h" 2#include "builtins.h" 3#include "error.h" 4#include "eval.h" 5#include "intern.h" 6#include "lexer.h" 7#include "scope.h" 8#include "source.h" 9#include "stdio.h" 10#include "syntax.h" 11#include "error.h" 12#include "value.h" 13#include <string.h> 14#define generate_comp_binop(op_name, op_expr) \ 15value_t * op_name(gc_t *gc, value_t **args, size_t num_args) { \ 16 if (num_args != 2) \ 17 return NULL; \ 18 if (args[0] == NULL || args[1] == NULL) return NULL; \ 19 if (args[0]->tag == VALUE_INT && args[1]->tag == VALUE_INT) { \ 20 long lhs = args[0]->as.integer; \ 21 long rhs = args[1]->as.integer; \ 22 int result = op_expr; \ 23 return(value_alloc_bool(gc,result)); \ 24 } else if ( (args[0]->tag == VALUE_FLOAT || args[0]->tag == VALUE_INT) \ 25 && (args[1]->tag == VALUE_FLOAT || args[1]->tag == VALUE_INT) ) { \ 26 double lhs = (args[0]->tag == VALUE_FLOAT) ? args[0]->as.floating : (double)args[0]->as.integer; \ 27 double rhs = (args[0]->tag == VALUE_FLOAT) ? args[1]->as.floating : (double)args[1]->as.integer; \ 28 int result = op_expr; \ 29 return(value_alloc_bool(gc,result)); \ 30 } else return NULL; \ 31} 32bool primop_eq_impl(value_t *arg0, value_t *arg1) { 33 if (arg0 == NULL || arg1 == NULL) return true; 34 if (arg0->tag == VALUE_INT && arg1->tag == VALUE_INT) { 35 return (arg0->as.integer == arg1->as.integer); 36 } else if ( (arg0->tag == VALUE_FLOAT || arg0->tag == VALUE_INT) 37 && (arg1->tag == VALUE_FLOAT || arg1->tag == VALUE_INT) ) { 38 double lhs = (arg0->tag == VALUE_FLOAT) ? arg0->as.floating : (double)arg0->as.integer; 39 double rhs = (arg0->tag == VALUE_FLOAT) ? arg1->as.floating : (double)arg1->as.integer; 40 return (lhs==rhs); 41 } else if ( arg0->tag == VALUE_STRING && arg1->tag == VALUE_STRING) { 42 return (strcmp(arg0->as.string.string, arg1->as.string.string) == 0); 43 } else if ( arg0->tag == VALUE_BUILTIN && arg1->tag == VALUE_BUILTIN) { 44 return (arg0->as.builtin == arg1->as.builtin); 45 } else if ( arg0->tag == VALUE_CLOSURE && arg1->tag == VALUE_CLOSURE) { 46 return (arg0 == arg1); 47 } else if ( arg0->tag == VALUE_CONSTRUCTOR && arg1->tag == VALUE_CONSTRUCTOR) { 48 if (arg0->as.constructor.name == arg1->as.constructor.name 49 && arg0->as.constructor.num_args == arg1->as.constructor.num_args) { 50 for (int i = 0; i < arg0->as.constructor.num_args; i++) { 51 if (!primop_eq_impl(arg0->as.constructor.args[i],arg1->as.constructor.args[i])) 52 return false; 53 } 54 return true; 55 } 56 } 57} 58value_t * primop_eq(gc_t *gc, value_t **args, size_t num_args) { 59 if (num_args != 2) 60 return NULL; 61 return value_alloc_bool(gc, primop_eq_impl(args[0], args[1])); 62} 63value_t * primop_noteq(gc_t *gc, value_t **args, size_t num_args) { 64 if (num_args != 2) 65 return NULL; 66 return value_alloc_bool(gc, !primop_eq_impl(args[0], args[1])); 67} 68#define generate_arith_binop(op_name, op_expr) \ 69 value_t * op_name(gc_t *gc, value_t **args, size_t num_args) { \ 70 if (num_args != 2) \ 71 return NULL; \ 72 if (args[0] == NULL || args[1] == NULL) return NULL; \ 73 if (args[0]->tag == VALUE_INT && args[1]->tag == VALUE_INT) { \ 74 long lhs = args[0]->as.integer; \ 75 long rhs = args[1]->as.integer; \ 76 long result = op_expr; \ 77 return value_alloc_int(gc, result); \ 78 } else if ( (args[0]->tag == VALUE_FLOAT || args[0]->tag == VALUE_INT) \ 79 && (args[1]->tag == VALUE_FLOAT || args[1]->tag == VALUE_INT) ) { \ 80 double lhs = (args[0]->tag == VALUE_FLOAT) ? args[0]->as.floating : (double)args[0]->as.integer; \ 81 double rhs = (args[0]->tag == VALUE_FLOAT) ? args[1]->as.floating : (double)args[1]->as.integer; \ 82 return value_alloc_float(gc, op_expr); \ 83 } else return NULL; \ 84 } 85generate_arith_binop(primop_plus, lhs + rhs) 86generate_arith_binop(primop_minus, lhs - rhs) 87generate_arith_binop(primop_mult, lhs * rhs) 88generate_arith_binop(primop_div, lhs / rhs) 89generate_arith_binop(primop_mod, (long)lhs % (long)rhs) 90generate_arith_binop(primop_idiv, (long)lhs / (long)rhs) 91 92generate_comp_binop(primop_greater, lhs > rhs) 93generate_comp_binop(primop_lesser, lhs < rhs) 94generate_comp_binop(primop_greatereq, lhs >= rhs) 95generate_comp_binop(primop_lessereq, lhs <= rhs) 96 97 98int main(int argc, char**argv) { 99 source_t *source = source_alloc_from_file("test.hito"); 100 lexer_t *lexer = lexer_alloc(source); 101 token_t tok; 102 intern_table_t *table = intern_table_alloc(); 103 builtins_t *builtins = builtins_alloc(); 104 builtins_add(builtins, intern(table,"+"),primop_plus); 105 builtins_add(builtins, intern(table,"-"),primop_minus); 106 builtins_add(builtins, intern(table,"mod"),primop_mod); 107 builtins_add(builtins, intern(table,"/"),primop_div); 108 builtins_add(builtins, intern(table,"div"),primop_idiv); 109 builtins_add(builtins, intern(table,"*"),primop_mult); 110 111 builtins_add(builtins, intern(table,">"),primop_greater); 112 builtins_add(builtins, intern(table,"<"),primop_lesser); 113 builtins_add(builtins, intern(table,">="),primop_greatereq); 114 builtins_add(builtins, intern(table,"<="),primop_lessereq); 115 builtins_add(builtins, intern(table,"="),primop_eq); 116 builtins_add(builtins, intern(table,"/="),primop_noteq); 117 expr_t *expr = syntax_parse_expr(lexer, builtins, table); 118 printf("%p\n", expr); 119 if (expr == NULL) return 1; 120 syntax_dump_expr(expr); 121 printf("\n"); 122 gc_t *gc = gc_alloc(); 123 value_t *v = eval(expr, gc); 124 value_debug_dump(v); 125 printf("\n"); 126}