- Timestamp:
- 05/05/08 07:28:23 (7 months ago)
- Location:
- lang/c/misc/mlisp
- Files:
-
- 10 modified
-
compiler/compiler.cpp (modified) (4 diffs)
-
compiler/compiler.h (modified) (1 diff)
-
sexp/inner.h (modified) (1 diff)
-
sexp/sexp.cpp (modified) (1 diff)
-
sexp/sprint.cpp (modified) (2 diffs)
-
sexp/sutil.cpp (modified) (1 diff)
-
sexp/sutil.h (modified) (1 diff)
-
test/main.cpp (modified) (10 diffs)
-
vm/op.h (modified) (1 diff)
-
vm/vm.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lang/c/misc/mlisp/compiler/compiler.cpp
r11110 r11144 8 8 #include "op.h" 9 9 #include "inner.h" 10 11 extern SExp evaluate(SExp code); 12 13 14 static SExp s_macros; 10 15 11 16 … … 75 80 } 76 81 } else { 77 return compile_pair_loop(cdr(args), compile(car(args), e, list(2, intern("argument"), c)), e, next);82 return compile_pair_loop(cdr(args), compile(car(args), e, list(2, ARGUMENT, c)), e, next); 78 83 } 79 84 } … … 127 132 } 128 133 134 135 136 /// �}�N���� 137 static void compile_defmacro(SExp name, SExp vars, SExp body) { 138 SExp mac = cons(name, cons(intern("lambda"), cons(vars, body))); 139 s_macros = cons(mac, s_macros); 140 } 141 142 SExp is_macro(SExp name) { 143 return assoc(name, s_macros); 144 } 145 146 /// �}�N���Ăяo���R�[�h�쐬 147 static SExp quotize(SExp s) { 148 return list(2, intern("quote"), s); 149 } 150 static SExp gen_macro_call(SExp m, SExp x) { 151 return cons(cdr(m), mapcar(quotize, cdr(x))); 152 } 153 154 /// �}�N����i�W�J 155 SExp macroexpand_1(SExp m, SExp x) { 156 SExp code = gen_macro_call(m, x); 157 return evaluate(code); 158 } 159 160 /// �}�N���K�p 161 static SExp compile_macro_apply(SExp m, SExp x, SExp e, SExp next) { 162 SExp trans = macroexpand_1(m, x); 163 return compile(trans, e, next); 164 } 165 166 167 168 /// �o�b�N�N�H�[�g�̕ϊ� 169 170 static SExp transform_quasiquote_loop(SExp x) { 171 if (!consp(x)) return list(2, intern("quote"), list(1, x)); 172 else if (eq(car(x), intern("unquote"))) return list(2, intern("list"), cadr(x)); 173 else if (eq(car(x), intern("unquote-splicing"))) return cadr(x); 174 else return list(2, intern("list"), cons(intern("append"), mapcar(transform_quasiquote_loop, x))); 175 } 176 177 static SExp transform_quasiquote(SExp x) { 178 SExp res = transform_quasiquote_loop(x); 179 SExp hd = car(res); 180 if (eq(hd, intern("list"))) return cadr(res); 181 else if (eq(hd, intern("quote"))) return list(2, intern("quote"), car(cadr(res))); 182 else { assert(!"unexpected"); return nil; } 183 } 184 185 /// ����void init_compile(void) { 186 s_macros = nil; 187 } 188 129 189 /// �P�̎�����p�C�� 130 190 SExp compile(SExp x, SExp e, SExp next) { … … 136 196 return list(3, REFER, access, next); 137 197 } else if (consp(x)) { 138 SExp op = car(x); 139 if (eq(op, intern("quote"))) { 140 SExp obj = cadr(x); 141 return list(3, CONSTANT, obj, next); 142 } else if (eq(op, intern("lambda"))) { 143 SExp vars = cadr(x); 144 SExp body = cddr(x); 145 return list(3, CLOSE, compile_block(body, extend(e, vars), cons(RETURN, nil)), next); 146 } else if (eq(op, intern("if"))) { 147 SExp test = cadr(x); 148 SExp then = caddr(x); 149 SExp thenc = compile(then, e, next); 150 SExp els, elsec; 151 SExp ddd = cdddr(x); 152 if (!nilp(ddd)) els = cadddr(x); 153 else els = nil; 154 elsec = compile(els, e, next); 155 return compile(test, e, list(3, TEST, thenc, elsec)); 156 } else if (eq(op, intern("set!"))) { 157 SExp var = cadr(x); 158 SExp xx = caddr(x); 159 return compile_set(ASSIGN, var, xx, e, next, false); 160 } else if (eq(op, intern("define"))) { 161 SExp var = cadr(x); 162 SExp body = cddr(x); 163 return compile_define(var, body, e, next); 164 } else if (eq(op, intern("call/cc"))) { 165 SExp xx = cadr(x); 166 SExp c = list(2, CONTI, list(2, ARGUMENT, compile(xx, e, cons(APPLY, nil)))); 167 if (tailp(next)) 168 return c; 169 else 170 return list(3, FRAME, c, next); 198 SExp m = is_macro(car(x)); 199 if (!nilp(m)) { 200 return compile_macro_apply(m, x, e, next); 171 201 } else { 172 return compile_pair_loop(cdr(x), compile(car(x), e, cons(APPLY, nil)), e, next); 202 SExp op = car(x); 203 if (eq(op, intern("quote"))) { 204 SExp obj = cadr(x); 205 return list(3, CONSTANT, obj, next); 206 } else if (eq(op, intern("quasiquote"))) { 207 SExp obj = cadr(x); 208 SExp trans = transform_quasiquote(obj); 209 return compile(trans, e, next); 210 } else if (eq(op, intern("unquote"))) { 211 compile_error(ERR_UNEXPECTED); 212 return nil; 213 } else if (eq(op, intern("unquote-splicing"))) { 214 compile_error(ERR_UNEXPECTED); 215 return nil; 216 } else if (eq(op, intern("lambda"))) { 217 SExp vars = cadr(x); 218 SExp body = cddr(x); 219 return list(3, CLOSE, compile_block(body, extend(e, vars), cons(RETURN, nil)), next); 220 } else if (eq(op, intern("if"))) { 221 SExp test = cadr(x); 222 SExp then = caddr(x); 223 SExp thenc = compile(then, e, next); 224 SExp els, elsec; 225 SExp ddd = cdddr(x); 226 if (!nilp(ddd)) els = cadddr(x); 227 else els = nil; 228 elsec = compile(els, e, next); 229 return compile(test, e, list(3, TEST, thenc, elsec)); 230 } else if (eq(op, intern("set!"))) { 231 SExp var = cadr(x); 232 SExp xx = caddr(x); 233 return compile_set(ASSIGN, var, xx, e, next, false); 234 } else if (eq(op, intern("define"))) { 235 SExp var = cadr(x); 236 SExp body = cddr(x); 237 return compile_define(var, body, e, next); 238 } else if (eq(op, intern("call/cc"))) { 239 SExp xx = cadr(x); 240 SExp c = list(2, CONTI, list(2, ARGUMENT, compile(xx, e, cons(APPLY, nil)))); 241 if (tailp(next)) 242 return c; 243 else 244 return list(3, FRAME, c, next); 245 } else if (eq(op, intern("defmacro"))) { 246 SExp name = cadr(x); 247 SExp vars = caddr(x); 248 SExp body = cdddr(x); 249 compile_defmacro(name, vars, body); 250 return next; 251 } else { 252 return compile_pair_loop(cdr(x), compile(car(x), e, cons(APPLY, nil)), e, next); 253 } 173 254 } 174 255 } else { -
lang/c/misc/mlisp/compiler/compiler.h
r11061 r11144 11 11 #endif 12 12 13 void init_compile(void); 13 14 SExp compile(SExp x, SExp e, SExp next); 14 15 SExp compile_block(SExp sexps, SExp e, SExp next); 16 17 SExp is_macro(SExp name); 18 SExp macroexpand_1(SExp m, SExp x); 15 19 16 20 #ifdef __cplusplus -
lang/c/misc/mlisp/sexp/inner.h
r11059 r11144 25 25 ERR_TYPE_REQUIRED, 26 26 ERR_UNDEFINED_SYMBOL, 27 ERR_UNEXPECTED, 27 28 }; 28 29 -
lang/c/misc/mlisp/sexp/sexp.cpp
r11059 r11144 22 22 "type required: %s", 23 23 "undefined symbol", 24 "unexpected", 24 25 }; 25 26 -
lang/c/misc/mlisp/sexp/sprint.cpp
r11057 r11144 1 1 #include "inner.h" 2 #include "sutil.h" 2 3 3 4 static void print_rec(SExp s); … … 30 31 { 31 32 SExp a = car(s); 32 if (eq(a, intern("quote")) ) {33 if (eq(a, intern("quote")) && singlep(cdr(s))) { 33 34 printf("'"); 34 35 print_rec(car(cdr(s))); -
lang/c/misc/mlisp/sexp/sutil.cpp
r11057 r11144 62 62 } 63 63 64 SExp mapcar(SExp (*fn)(SExp), SExp ls) { 65 SExp acc = nil; 66 for (; !nilp(ls); ls = cdr(ls)) { 67 acc = cons(fn(car(ls)), acc); 68 } 69 return nreverse(acc); 70 } 71 72 SExp assoc(SExp sym, SExp alist) { 73 for (; consp(alist); alist = cdr(alist)) { 74 SExp elem = car(alist); 75 if (eq(sym, car(elem))) return elem; 76 } 77 return nil; 78 } 79 80 64 81 65 82 int singlep(SExp ls) { -
lang/c/misc/mlisp/sexp/sutil.h
r11058 r11144 29 29 SExp nreverse(SExp s); 30 30 31 /// ���X�g�̊e�v�f�Ɋ���p�i���X�g�͂P��� 32 SExp mapcar(SExp (*fn)(SExp), SExp ls); 33 34 /// alist ((key . value) ...) ������ 35 SExp assoc(SExp sym, SExp alist); 36 37 31 38 /// ���X�g�ŗv�f���ЂƂ����H 32 39 int singlep(SExp ls); -
lang/c/misc/mlisp/test/main.cpp
r11059 r11144 31 31 32 32 33 SExp comp_env,run_env;33 SExp g_comp_env, g_run_env; 34 34 35 35 int load(const char* fn); … … 41 41 42 42 SExp run(SExp c) { 43 return vm(nil, c, run_env, nil, nil);43 return vm(nil, c, g_run_env, nil, nil); 44 44 } 45 45 46 46 SExp evaluate(SExp code) { 47 47 SExp halt_code = cons(HALT, nil); 48 SExp c = compile(code, comp_env, halt_code);48 SExp c = compile(code, g_comp_env, halt_code); 49 49 return run(c); 50 50 } … … 86 86 SExp d = cadr(arg); 87 87 return eq(a, d) ? t : nil; 88 } 89 90 static SExp builtin_rplaca(SExp arg) { 91 SExp a = car(arg); 92 SExp d = cadr(arg); 93 rplaca(a, d); 94 return nil; 95 } 96 97 static SExp builtin_rplacd(SExp arg) { 98 SExp a = car(arg); 99 SExp d = cadr(arg); 100 rplacd(a, d); 101 return nil; 88 102 } 89 103 … … 210 224 SExp code = car(arg); 211 225 SExp halt_code = cons(HALT, nil); 212 return compile(code, comp_env, halt_code); 213 } 226 return compile(code, g_comp_env, halt_code); 227 } 228 229 static SExp builtin_macroexpand_1(SExp arg) { 230 SExp code = car(arg); 231 if (consp(code)) { 232 SExp m = is_macro(car(code)); 233 if (!nilp(m)) return macroexpand_1(m, code); 234 else return code; 235 } else { 236 return code; 237 } 238 } 239 240 241 242 static SExp builtin_list(SExp arg) { 243 // @todo: �j�Ă������m���߂� return arg; 244 } 245 246 static SExp cat(SExp a, SExp b) { 247 if (!consp(a)) return b; 248 else return cons(car(a), cat(cdr(a), b)); 249 } 250 251 static SExp builtin_append(SExp arg) { 252 if (!consp(arg)) return arg; 253 else if (nilp(cdr(arg))) return car(arg); 254 else return cat(car(arg), builtin_append(cdr(arg))); 255 } 256 257 static SExp builtin_reverse(SExp arg) { 258 return reverse(car(arg)); 259 } 260 261 static SExp builtin_nreverse(SExp arg) { 262 return nreverse(car(arg)); 263 } 264 265 static SExp builtin_global_symbols(SExp arg) { 266 return car(g_comp_env); 267 } 268 269 214 270 215 271 static void add_proctbl(SExp* pcenv, SExp* prenv) { … … 227 283 { "car", builtin_car, FALSE, 1, 1, }, 228 284 { "cdr", builtin_cdr, FALSE, 1, 1, }, 229 { "consp", builtin_consp, FALSE, 1, 1, }, 230 { "eq", builtin_eq, FALSE, 2, 2, }, 285 { "pair?", builtin_consp, FALSE, 1, 1, }, 286 { "eq?", builtin_eq, FALSE, 2, 2, }, 287 { "set-car!", builtin_rplaca, FALSE, 2, 2, }, 288 { "set-cdr!", builtin_rplacd, FALSE, 2, 2, }, 231 289 { "+", builtin_plus, FALSE, 0, -1, }, 232 290 { "-", builtin_difference, FALSE, 1, -1, }, … … 241 299 { "eval", builtin_eval, FALSE, 1, 1, }, 242 300 301 { "list", builtin_list, FALSE, 0, -1, }, 302 { "append", builtin_append, FALSE, 0, -1, }, 303 { "reverse", builtin_reverse, FALSE, 0, -1, }, 304 { "nreverse", builtin_nreverse, FALSE, 0, -1, }, 305 243 306 { "load", builtin_load, FALSE, 1, 1, }, 244 307 { "compile", builtin_compile, FALSE, 1, 1, }, 308 { "macroexpand-1", builtin_macroexpand_1, FALSE, 1, 1, }, 309 310 { "global-symbols", builtin_global_symbols, FALSE, 1, 1, }, 245 311 }; 246 312 for (int i=0; i<sizeof(tbl)/sizeof(*tbl); ++i) { … … 282 348 add_consttbl(&cenv, &renv); 283 349 284 comp_env = cons(cenv, nil);285 run_env = cons(renv, nil);350 g_comp_env = cons(cenv, nil); 351 g_run_env = cons(renv, nil); 286 352 } 287 353 … … 290 356 FILE* fp = fopen(fn, "r"); 291 357 SExp code = nil; 292 if (fp != NULL) {358 if (fp == NULL) { 293 359 // runtime_error(); 294 360 } else { … … 300 366 } 301 367 SExp halt_code = cons(HALT, nil); 302 code = compile_block(nreverse(acc), comp_env, halt_code);368 code = compile_block(nreverse(acc), g_comp_env, halt_code); 303 369 304 370 fclose(fp); … … 347 413 348 414 mlisp_new(&vtbl); 415 init_compile(); 349 416 init_env(); 350 417 if (argc >= 2) { -
lang/c/misc/mlisp/vm/op.h
r11110 r11144 6 6 7 7 #if 1 8 #define HALT intern(" halt")9 #define REFER intern(" refer")10 #define CONSTANT intern(" constant")11 #define CLOSE intern(" close")12 #define TEST intern(" test")13 #define ASSIGN intern(" assign")14 #define DEFINE intern(" define")15 #define CONTI intern(" conti")16 #define NUATE intern(" nuate")17 #define FRAME intern(" frame")18 #define ARGUMENT intern(" argument")19 #define APPLY intern(" apply")20 #define RETURN intern(" return")8 #define HALT intern("HALT") 9 #define REFER intern("REFER") 10 #define CONSTANT intern("CONSTANT") 11 #define CLOSE intern("CLOSE") 12 #define TEST intern("TEST") 13 #define ASSIGN intern("ASSIGN") 14 #define DEFINE intern("DEFINE") 15 #define CONTI intern("CONTI") 16 #define NUATE intern("NUATE") 17 #define FRAME intern("FRAME") 18 #define ARGUMENT intern("ARGUMENT") 19 #define APPLY intern("APPLY") 20 #define RETURN intern("RETURN") 21 21 22 22 #else -
lang/c/misc/mlisp/vm/vm.cpp
r11061 r11144 15 15 16 16 static void runtime_error(const char* msg) { 17 assert(!msg); 17 printf("%s\n", msg); 18 error(ERR_UNEXPECTED); 18 19 } 19 20 … … 35 36 for (int elt = s2int(cdr(access)); ; --elt) { 36 37 if (nilp(r)) { 37 SExp le = car(e);38 if (!nilp(le)) {39 extend_run_env(car(e), elt + 1);38 if (!b_extend) { 39 runtime_error("illegal access"); 40 return nil; 40 41 } else { 41 rplaca(e, replicate(elt + 1, nil)); 42 SExp le = car(e); 43 if (!nilp(le)) { 44 extend_run_env(car(e), elt + 1); 45 } else { 46 rplaca(e, replicate(elt + 1, nil)); 47 } 48 49 r = car(e); elt = s2int(cdr(access)); 42 50 } 43 44 r = car(e); elt = s2int(cdr(access));45 51 } 46 52 if (elt == 0) return r;
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)