|
@ -1,6 +1,6 @@ |
|
|
# main.leg -- C parser + interpreter |
|
|
# main.leg -- C parser + interpreter |
|
|
# |
|
|
# |
|
|
# Last edited: 2025-02-05 12:43:42 by piumarta on m1mbp |
|
|
|
|
|
|
|
|
# Last edited: 2025-02-05 13:53:41 by piumarta on xubuntu |
|
|
|
|
|
|
|
|
%{ |
|
|
%{ |
|
|
; |
|
|
; |
|
@ -105,8 +105,8 @@ char *binaryName(int op) { |
|
|
|
|
|
|
|
|
#undef _ |
|
|
#undef _ |
|
|
|
|
|
|
|
|
#define _do_primitives(_) \ |
|
|
|
|
|
_(printf) _(assert) _(malloc) _(free) _(exit) _(abort) _(sqrtf) |
|
|
|
|
|
|
|
|
#define _do_primitives(_) \ |
|
|
|
|
|
_(printf) _(assert) _(malloc) _(free) _(exit) _(abort) _(atoi) _(sqrtf) |
|
|
|
|
|
|
|
|
#define _(X) oop s_##X = 0; |
|
|
#define _(X) oop s_##X = 0; |
|
|
_do_primitives(_) |
|
|
_do_primitives(_) |
|
@ -2389,6 +2389,17 @@ oop pointerMemory(oop arg) |
|
|
return base; |
|
|
return base; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
char *pointerString(oop ptr) |
|
|
|
|
|
{ |
|
|
|
|
|
oop mem = pointerMemory(ptr); |
|
|
|
|
|
if (nil == mem) fatal("cannot get string from pointer: ", toString(ptr)); |
|
|
|
|
|
char *addr = get(mem, Memory,base); |
|
|
|
|
|
int size = get(mem, Memory,size); |
|
|
|
|
|
char *term = memchr(addr, '\0', size); |
|
|
|
|
|
if (!term) fatal("unterminated string: %s", toString(ptr)); |
|
|
|
|
|
return addr; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
oop prim_printf(int argc, oop *argv, oop env) // array |
|
|
oop prim_printf(int argc, oop *argv, oop env) // array |
|
|
{ |
|
|
{ |
|
|
if (argc < 1) fatal("printf: no format string"); |
|
|
if (argc < 1) fatal("printf: no format string"); |
|
@ -2454,16 +2465,9 @@ oop prim_printf(int argc, oop *argv, oop env) // array |
|
|
case Array: { |
|
|
case Array: { |
|
|
oop type = elementType(arg); |
|
|
oop type = elementType(arg); |
|
|
if (t_char == type) { |
|
|
if (t_char == type) { |
|
|
oop mem = pointerMemory(arg); |
|
|
|
|
|
if (nil != mem) { |
|
|
|
|
|
char *addr = get(mem, Memory,base); |
|
|
|
|
|
int size = get(mem, Memory,size); |
|
|
|
|
|
char *term = memchr(addr, '\0', size); |
|
|
|
|
|
if (!term) |
|
|
|
|
|
fatal("printf: %%s with unterminated string: %s", toString(arg)); |
|
|
|
|
|
n += printf(buf, addr); |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
char *addr = pointerString(arg); |
|
|
|
|
|
n += printf(buf, addr); |
|
|
|
|
|
continue; |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
@ -2549,6 +2553,15 @@ oop prim_abort(int argc, oop *argv, oop env) // array |
|
|
return nil; |
|
|
return nil; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
oop prim_atoi(int argc, oop *argv, oop env) // array |
|
|
|
|
|
{ |
|
|
|
|
|
if (argc != 1) fatal("atoi: wrong number of arguments"); |
|
|
|
|
|
oop arg = argv[0]; |
|
|
|
|
|
if (!is(Pointer, arg) || t_pchar != get(arg, Pointer,type)) |
|
|
|
|
|
fatal("atoi: illegal argument: %s", toString(arg)); |
|
|
|
|
|
return newInteger(atoi(pointerString(arg))); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
oop prim_sqrtf(int argc, oop *argv, oop env) // array |
|
|
oop prim_sqrtf(int argc, oop *argv, oop env) // array |
|
|
{ |
|
|
{ |
|
|
if (argc != 1) fatal("sqrtf: wrong number of arguments"); |
|
|
if (argc != 1) fatal("sqrtf: wrong number of arguments"); |
|
|