Ver a proveniência

Fix circular printing, comparison and pass scope to primitives

pull/15/head
mtardy há 4 anos
ascendente
cometimento
2c057a58f9
6 ficheiros alterados com 128 adições e 56 eliminações
  1. +16
    -0
      bootstrap.txt
  2. +55
    -17
      object.c
  3. +45
    -36
      parse.leg
  4. +6
    -0
      test-module.txt
  5. +6
    -0
      test-require.txt
  6. +0
    -3
      test3.txt

+ 16
- 0
bootstrap.txt Ver ficheiro

@ -0,0 +1,16 @@
var __requires__ = {}
fun require(__fileName__) {
if (__requires__[__fileName__] != null) {
return __requires__[__fileName__]
}
import(__fileName__);
__requires__[__fileName__]= scope();
return scope();
}
fun println() {
apply(print, __arguments__);
print("\n");
__arguments__;
}

+ 55
- 17
object.c Ver ficheiro

@ -1,5 +1,6 @@
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <sysexits.h>
#include <assert.h>
@ -85,7 +86,7 @@ struct Symbol {
#endif //SYMBOL_PAYLOAD
};
typedef oop (*primitive_t)(oop params);
typedef oop (*primitive_t)(oop scope, oop params);
struct Function {
type_t type;
@ -177,7 +178,7 @@ DECLARE_STRING_BUFFER(char, StringBuffer);
void print(oop ast);
void println(oop ast);
void printOn(StringBuffer *buf, oop obj);
void printOn(StringBuffer *buf, oop obj, int indent);
int getInteger(oop obj)
{
@ -458,6 +459,40 @@ oop map_values(oop map)
return values;
}
DECLARE_BUFFER(oop, OopStack);
OopStack printing = BUFFER_INITIALISER;
#define OopStack_push(s, o) OopStack_append(s, o)
oop OopStack_pop(OopStack *s)
{
if (s->position < 1) {
return null;
}
return s->contents[--(s->position)];
}
int OopStack_includes(OopStack *s, oop map)
{
for (size_t i=0; i < s->position; ++i) {
if (s->contents[i] == map) {
return 1;
}
}
return 0;
}
void indentOn(StringBuffer *buf, int indent)
{
for (size_t i = 0; i < indent; i++) {
if (isatty(fileno(stdout))) {
StringBuffer_appendString(buf, "\033[90m|\033[0m");
} else {
StringBuffer_appendString(buf, "|");
}
StringBuffer_appendString(buf, " ");
}
}
void map_printOn(StringBuffer *buf, oop map, int ident)
{
assert(is(Map, map));
@ -467,31 +502,30 @@ void map_printOn(StringBuffer *buf, oop map, int ident)
StringBuffer_append(buf, '}');
return;
}
if (OopStack_includes(&printing, map)) {
StringBuffer_appendString(buf, "<cycle>");
return;
}
OopStack_push(&printing, map);
for (size_t i = 0; i < map_size(map); i++) {
StringBuffer_append(buf, '\n');
for (size_t i = 0; i < ident; i++) {
if (isatty(fileno(stdout))) {
StringBuffer_appendString(buf, "\033[90m|\033[0m");
} else {
StringBuffer_appendString(buf, "|");
}
StringBuffer_appendString(buf, " ");
}
indentOn(buf, ident);
// todo: a key could be a map itself
printOn(buf, get(map, Map, elements)[i].key);
printOn(buf, get(map, Map, elements)[i].key, ident);
StringBuffer_appendString(buf, ": ");
oop rhs = get(map, Map, elements)[i].value;
if (getType(rhs) == Map) {
map_printOn(buf, rhs, ident + 1);
} else {
printOn(buf, rhs);
printOn(buf, rhs, ident);
}
if (i < map_size(map) - 1) StringBuffer_append(buf, ',');
if (ident == 1 && i == map_size(map) - 1) StringBuffer_append(buf, '\n');
}
OopStack_pop(&printing);
}
void printOn(StringBuffer *buf, oop obj)
void printOn(StringBuffer *buf, oop obj, int indent)
{
assert(obj);
switch (getType(obj)) {
@ -520,14 +554,18 @@ void printOn(StringBuffer *buf, oop obj)
} else {
StringBuffer_appendString(buf, "Primitive:");
}
printOn(buf, get(obj, Function, name));
printOn(buf, get(obj, Function, name), indent);
StringBuffer_append(buf, '(');
printOn(buf, get(obj, Function, param));
printOn(buf, get(obj, Function, param), indent + 1);
if (get(obj, Function, param) != null) {
StringBuffer_append(buf, '\n');
indentOn(buf, indent);
}
StringBuffer_append(buf, ')');
return;
}
case Map: {
map_printOn(buf, obj, 0);
map_printOn(buf, obj, indent);
return;
}
}
@ -538,7 +576,7 @@ char *printString(oop obj)
{
static StringBuffer buf= BUFFER_INITIALISER;
StringBuffer_clear(&buf);
printOn(&buf, obj);
printOn(&buf, obj, 0);
return StringBuffer_contents(&buf);
}

+ 45
- 36
parse.leg Ver ficheiro

@ -485,7 +485,7 @@ oop newFunc(oop name, oop param, oop body, oop fixed)
return func;
}
oop apply(oop func, oop args);
oop apply(oop scope, oop func, oop args);
oop getSyntaxId(int n, oop key)
{
@ -625,7 +625,7 @@ exp = VAR l:ident ASSIGN e:exp { $$ = newDeclarati
| l:IDENT o:assignOp e:exp { $$ = newAssign(Assign_proto, l, o, e) }
| l:postfix DOT i:IDENT o:assignOp e:exp { $$ = newSetMap(SetMember_proto, l, i, o, e) }
| l:postfix LBRAC i:exp RBRAC o:assignOp e:exp { $$ = newSetMap(SetIndex_proto, l, i, o, e) }
| l:syntax2 a:argumentList s:block { $$ = (map_append(a, s), apply(l, a)) }
| l:syntax2 a:argumentList s:block { $$ = (map_append(a, s), apply(globals, l, a)) }
| c:cond { $$ = c }
ident = l:IDENT { $$ = l }
@ -724,7 +724,7 @@ prefix = PLUS n:prefix { $$= n }
postfix = i:value ( DOT s:IDENT a:argumentList { i = newInvoke(i, s, a) }
| DOT s:IDENT !assignOp { i = newGetMap(GetMember_proto, i, s) }
| LBRAC p:exp RBRAC !assignOp { i = newGetMap(GetIndex_proto, i, p) }
| a:argumentList { i = (null != getSyntax(1, i)) ? apply(getSyntax(1, i), a) : newCall(i, a) }
| a:argumentList { i = (null != getSyntax(1, i)) ? apply(globals, getSyntax(1, i), a) : newCall(i, a) }
| PLUSPLUS { i = newPostIncrement(i) }
| MINUSMINUS { i = newPostDecrement(i) }
) * { $$ = i }
@ -1114,7 +1114,7 @@ oop eval(oop scope, oop ast)
oop condition = map_get(ast, condition_symbol );
oop consequent = map_get(ast, consequent_symbol);
oop alternate = map_get(ast, alternate_symbol );
return eval(scope, isTrue(eval(scope, condition)) ? consequent : alternate);
return eval(scope, isTrue(eval(scope, condition)) ? consequent : alternate);
}
case t_While: {
oop condition = map_get(ast, condition_symbol );
@ -1335,7 +1335,7 @@ oop eval(oop scope, oop ast)
jbRecPop();
return result;
}
return get(func, Function, primitive)(args);
return get(func, Function, primitive)(scope, args);
}
case t_Invoke: {
// this is what differs from t_call
@ -1349,7 +1349,7 @@ oop eval(oop scope, oop ast)
oop args = evalArgs(scope, map_get(ast, args_symbol));
if (NULL != get(func, Function, primitive)) {
return get(func, Function, primitive)(args);
return get(func, Function, primitive)(scope, args);
}
oop param = get(func, Function, param);
oop localScope = map_zip(param, args);
@ -1547,8 +1547,18 @@ oop eval(oop scope, oop ast)
BINARY(Bitor, | );
BINARY(Bitxor, ^ );
BINARY(Bitand, & );
BINARY(Equal, ==);
BINARY(Noteq, !=);
// BINARY(Equal, ==);
// BINARY(Noteq, !=);
case t_Equal: {
oop lhs = eval(scope, map_get(ast, lhs_symbol));
oop rhs = eval(scope, map_get(ast, rhs_symbol));
return makeInteger(0 == oopcmp(lhs, rhs));
}
case t_Noteq: {
oop lhs = eval(scope, map_get(ast, lhs_symbol));
oop rhs = eval(scope, map_get(ast, rhs_symbol));
return makeInteger(0 != oopcmp(lhs, rhs));
}
BINARY(Less, < );
BINARY(Lesseq, <=);
BINARY(Greatereq, >=);
@ -1676,7 +1686,7 @@ oop eval(oop scope, oop ast)
return null;
}
oop prim_exit(oop params)
oop prim_exit(oop scope, oop params)
{
int status= 0;
if (map_hasIntegerKey(params, 0)) {
@ -1686,7 +1696,7 @@ oop prim_exit(oop params)
exit(status);
}
oop prim_keys(oop params)
oop prim_keys(oop scope, oop params)
{
if (map_hasIntegerKey(params, 0)) {
oop arg= get(params, Map, elements)[0].value;
@ -1695,7 +1705,7 @@ oop prim_keys(oop params)
return null;
}
oop prim_values(oop params)
oop prim_values(oop scope, oop params)
{
if (map_hasIntegerKey(params, 0)) {
oop arg= get(params, Map, elements)[0].value;
@ -1704,7 +1714,7 @@ oop prim_values(oop params)
return null;
}
oop prim_length(oop params)
oop prim_length(oop scope, oop params)
{
if (map_hasIntegerKey(params, 0)) {
oop arg= get(params, Map, elements)[0].value;
@ -1726,7 +1736,7 @@ oop prim_length(oop params)
// ISSUE2: how can I tackle the 2 fprintf(stderr, "\nbreak/continue oustide of a loop\n") in prim_invoke and prim_apply
// in this situation it seems that I don't have access to any AST
oop prim_invoke(oop params)
oop prim_invoke(oop scope, oop params)
{
oop this= null; if (map_hasIntegerKey(params, 0)) this= get(params, Map, elements)[0].value;
oop func= null; if (map_hasIntegerKey(params, 1)) func= get(params, Map, elements)[1].value;
@ -1737,7 +1747,7 @@ oop prim_invoke(oop params)
exit(1);
}
if (NULL != get(func, Function, primitive)) {
return get(func, Function, primitive)(args);
return get(func, Function, primitive)(scope, args);
}
oop param = get(func, Function, param);
oop localScope = map_zip(param, args);
@ -1770,7 +1780,7 @@ oop prim_invoke(oop params)
return result;
}
oop apply(oop func, oop args)
oop apply(oop scope, oop func, oop args)
{
if (!is(Function, func)) {
printf("cannot apply ");
@ -1778,7 +1788,7 @@ oop apply(oop func, oop args)
exit(1);
}
if (NULL != get(func, Function, primitive)) {
return get(func, Function, primitive)(args);
return get(func, Function, primitive)(scope, args);
}
oop param = get(func, Function, param);
oop localScope = map_zip(param, args);
@ -1810,19 +1820,19 @@ oop apply(oop func, oop args)
return result;
}
oop prim_apply(oop params) {
oop prim_apply(oop scope, oop params) {
oop func= null; if (map_hasIntegerKey(params, 0)) func= get(params, Map, elements)[0].value;
oop args= null; if (map_hasIntegerKey(params, 1)) args= get(params, Map, elements)[1].value;
return apply(func, args);
return apply(scope, func, args);
}
oop prim_clone(oop params)
oop prim_clone(oop scope, oop params)
{
if (map_hasIntegerKey(params, 0)) return clone(get(params, Map, elements)[0].value);
return null;
}
oop prim_print(oop params)
oop prim_print(oop scope, oop params)
{
assert(is(Map, params));
for (int i= 0; map_hasIntegerKey(params, i); ++i) {
@ -1831,13 +1841,6 @@ oop prim_print(oop params)
return params;
}
oop prim_println(oop params)
{
oop res= prim_print(params);
printf("\n");
return res;
}
oop evalArgs(oop scope, oop args)
{
int i = 0;
@ -1852,7 +1855,7 @@ oop evalArgs(oop scope, oop args)
oop AST= NULL;
void readEvalPrint(char *fileName)
void readEvalPrint(oop scope, char *fileName)
{
inputStackPush(fileName);
input_t *top= inputStack;
@ -1871,7 +1874,7 @@ void readEvalPrint(char *fileName)
continue;
} // EOF
if (opt_v > 1) println(yylval);
oop res = eval(globals, yylval);
oop res = eval(scope, yylval);
if (opt_v > 0) println(res);
assert(jbs == jtop);
}
@ -1898,7 +1901,7 @@ void readEvalPrint(char *fileName)
}
}
oop prim_import(oop params)
oop prim_import(oop scope, oop params)
{
if (map_hasIntegerKey(params, 0)) {
char *file= get(get(params, Map, elements)[0].value, String, value);
@ -1906,14 +1909,19 @@ oop prim_import(oop params)
yyctx->__limit--;
ungetc(yyctx->__buf[yyctx->__limit], inputStack->file);
}
readEvalPrint(file);
readEvalPrint(scope, file);
}
return null;
}
oop prim_scope(oop scope, oop params)
{
return scope;
}
#include <sys/resource.h>
oop prim_millis(oop params)
oop prim_millis(oop scope, oop params)
{
struct rusage ru;
getrusage(RUSAGE_SELF, &ru);
@ -1934,13 +1942,14 @@ int main(int argc, char **argv)
map_set(globals, intern("values") , makeFunction(prim_values, intern("values"), null, null, globals, null));
map_set(globals, intern("length") , makeFunction(prim_length, intern("length"), null, null, globals, null));
map_set(globals, intern("print") , makeFunction(prim_print, intern("print"), null, null, globals, null));
map_set(globals, intern("println"), makeFunction(prim_println, intern("println"), null, null, globals, null));
map_set(globals, intern("invoke") , makeFunction(prim_invoke, intern("invoke"), null, null, globals, null));
map_set(globals, intern("apply") , makeFunction(prim_apply, intern("apply"), null, null, globals, null));
map_set(globals, intern("clone") , makeFunction(prim_clone, intern("clone"), null, null, globals, null));
map_set(globals, intern("import") , makeFunction(prim_import, intern("import"), null, null, globals, null));
map_set(globals, intern("millis") , makeFunction(prim_millis, intern("millis"), null, null, globals, null));
map_set(globals, intern("scope"), makeFunction(prim_scope, intern("scope"), null, null, globals, null));
#define _DO(NAME) NAME##_symbol=intern(#NAME);
DO_SYMBOLS()
#undef _DO
@ -1964,16 +1973,16 @@ int main(int argc, char **argv)
++argv;
if (!strcmp(*argv, "-v")) ++opt_v;
else if (!strcmp(*argv, "-")) {
readEvalPrint(NULL);
readEvalPrint(globals, NULL);
repled= 1;
}
else {
readEvalPrint(*argv);
readEvalPrint(globals, *argv);
repled= 1;
}
}
if (!repled) {
readEvalPrint(NULL);
readEvalPrint(globals, NULL);
}
return 0;

+ 6
- 0
test-module.txt Ver ficheiro

@ -0,0 +1,6 @@
var pi = 3
fun sum(a, b) {
return a+b;
}
println("Hello from test-module.txt");

+ 6
- 0
test-require.txt Ver ficheiro

@ -0,0 +1,6 @@
// keep a reference to that function local scope that might otherwise been garbage collected
var mod = require("test-module.txt");
println(mod.sum(40, 2));
println(mod.pi);
var mod2 = require("test-module.txt");
println(mod2.pi);

+ 0
- 3
test3.txt Ver ficheiro

@ -1,3 +0,0 @@
println(666)
import "test-proto.txt"
println(12)

Carregando…
Cancelar
Guardar