From 0df1d03e90d0978e995b07d619ba1b3e6514d5e7 Mon Sep 17 00:00:00 2001 From: Theo Souchon Date: Mon, 16 Jan 2023 19:08:48 +0900 Subject: [PATCH] Switch between C & Parsimony fix --- ccmeta.leg | 153 ++++++++++++++++++------- parsimonyLibrary/boot.mc | 51 ++++++--- parsimonyLibrary/dynamicObject.mc | 65 +++++++---- tests-parsimony/parsimony-lang/008.c | 16 +++ tests-parsimony/parsimony-lang/008.out | 1 + tests-parsimony/parsimony-lang/009.c | 10 ++ tests-parsimony/parsimony-lang/009.out | 1 + tests-parsimony/realObject.c | 11 +- 8 files changed, 218 insertions(+), 90 deletions(-) create mode 100644 tests-parsimony/parsimony-lang/008.c create mode 100644 tests-parsimony/parsimony-lang/008.out create mode 100644 tests-parsimony/parsimony-lang/009.c create mode 100644 tests-parsimony/parsimony-lang/009.out diff --git a/ccmeta.leg b/ccmeta.leg index ff5f2f2..e0ff0c3 100644 --- a/ccmeta.leg +++ b/ccmeta.leg @@ -30,11 +30,12 @@ _DO(PostDecVariable) _DO(PostDecMember) _DO(PostDecIndex) \ _DO(GetVariable) _DO(GetMember) _DO(SetMember) _DO(GetIndex) _DO(SetIndex) \ _DO(Return) _DO(Break) _DO(Continue) _DO(Throw) _DO(Try) \ - _DO(Quote) /* _DO(Quasiquote) _DO(Unquote) */ \ + _DO(Quote) _DO(Quasiquote) /* _DO(Unquote) */ \ DO_C_PROTOS() #define META_PROTO_MAX t_Try +// C protos must begin with Comment because it is a sentinel #define DO_C_PROTOS() \ _DO(Comment) _DO(Token) \ _DO(C_declaration) _DO(C_stringLiteral) \ @@ -1347,7 +1348,7 @@ oop ensure(int id, oop s) { if (is(Map, s)) { oop protoSymbol = map_get(s, __proto___symbol); - // int protoNumber = get(map_get(protoSymbol, __name___symbol), Symbol, prototype); + // int protoNumber = get(map_get(map_get(s, __proto___symbol), __name___symbol), Symbol, prototype); switch(id) { case t_C_id: { if (map_get(protoSymbol, __name___symbol) != map_get(C_id_proto, __name___symbol)) { // map_get for tree copy because __name__ : C_id != __name__ : C_id @@ -1360,8 +1361,87 @@ oop ensure(int id, oop s) return s; } -%} +oop clone(oop obj) +{ + switch(getType(obj)) { + case Undefined: + case Integer: + case Float: + case Function: + case Symbol: + return obj; + case String: + return makeString(get(obj, String, value)); + case Map: { + struct Pair *elements= malloc(sizeof(struct Pair) * get(obj, Map, capacity)); + memcpy(elements, get(obj, Map, elements), sizeof(struct Pair) * get(obj, Map, capacity)); + oop map= malloc(sizeof(*obj)); + memcpy(map, obj, sizeof(*obj)); + set(map, Map, elements, elements); + return map; + } + } + return obj; +} +oop treeCopy(oop obj) +{ + switch(getType(obj)) { + case Undefined: + case Integer: + case Float: + case Function: + case Symbol: + return obj; + case String: + return makeString(get(obj, String, value)); + case Map: { + struct Pair *elements= malloc(sizeof(struct Pair) * get(obj, Map, size)); + memcpy(elements, get(obj, Map, elements), sizeof(struct Pair) * get(obj, Map, size)); + oop map= malloc(sizeof(*obj)); + memcpy(map, obj, sizeof(*obj)); + for (int i = 0; i { $$= new_C_id(yytex metaId = META_AT META_LPAREN m:meta_exp META_RPAREN { $$= m} -mmetaId = META_AT META_AT META_LPAREN m:meta_exp META_RPAREN { $$= m} +mmetaId = META_AT META_AT META_LPAREN m:meta_exp META_RPAREN { $$= m } ID = &{ !is_C_keyword(yytext) } @@ -2453,15 +2533,15 @@ META_FLOAT = < [-+]* [0-9]+ '.' [0-9]* ('e'[-+]*[0-9]+)? > { $$= make #--------------------------------------------- Meta operator ----------------------------------------------# -MO_OPERATION = META_BACKTICK ( MO_INITIALIZER i:initializer { $$= newUnary(Quote_proto, i) } - | MO_CONSTANT c:constant { $$= newUnary(Quote_proto, c) } - | MO_STATEMENT s:statement { $$= newUnary(Quote_proto, s) } - | MO_INTEGER i:integerConstant { $$= newUnary(Quote_proto, i) } - | MO_DECLARATION d:declaration { $$= newUnary(Quote_proto, d) } - | MO_STRING s:stringLiteral { $$= newUnary(Quote_proto, s) } - | MO_FUN f:functionDefinition { $$= newUnary(Quote_proto, f) } - | MO_ED e:externalDeclaration { $$= newUnary(Quote_proto, e) } - | MO_EXPRESSION e:expression { $$= newUnary(Quote_proto, e) } +MO_OPERATION = META_BACKTICK ( MO_INITIALIZER i:initializer { $$= newUnary(Quasiquote_proto, i) } + | MO_CONSTANT c:constant { $$= newUnary(Quasiquote_proto, c) } + | MO_STATEMENT s:statement { $$= newUnary(Quasiquote_proto, s) } + | MO_INTEGER i:integerConstant { $$= newUnary(Quasiquote_proto, i) } + | MO_DECLARATION d:declaration { $$= newUnary(Quasiquote_proto, d) } + | MO_STRING s:stringLiteral { $$= newUnary(Quasiquote_proto, s) } + | MO_FUN f:functionDefinition { $$= newUnary(Quasiquote_proto, f) } + | MO_ED e:externalDeclaration { $$= newUnary(Quasiquote_proto, e) } + | MO_EXPRESSION e:expression { $$= newUnary(Quasiquote_proto, e) } ) MO_INITIALIZER = 'initializer' ![(a-zA-Z0-9_] -- @@ -2601,29 +2681,6 @@ oop map_zip(oop map, oop keys, oop values) return map; } -oop clone(oop obj) -{ - switch(getType(obj)) { - case Undefined: - case Integer: - case Float: - case Function: - case Symbol: - return obj; - case String: - return makeString(get(obj, String, value)); - case Map: { - struct Pair *elements= malloc(sizeof(struct Pair) * get(obj, Map, capacity)); - memcpy(elements, get(obj, Map, elements), sizeof(struct Pair) * get(obj, Map, capacity)); - oop map= malloc(sizeof(*obj)); - memcpy(map, obj, sizeof(*obj)); - set(map, Map, elements, elements); - return map; - } - } - return obj; -} - struct Call { oop ast, function; @@ -2838,7 +2895,7 @@ oop newScope(oop parent) void delScope(oop scope) { assert(is(Map, scope)); if (scope->Map.flags & MAP_ENCLOSED) { - printf("IGNORE %p\n", scope); + // printf("IGNORE %p\n", scope); return; } scope->Map.pool= freeScopes; @@ -2866,28 +2923,29 @@ oop apply(oop scope, oop this, oop func, oop args, oop ast) switch (jbt) { case j_return: { untrace(ast); - delScope(localScope); + delScope(localScope); oop result = jbs->result; jbRecPop(); return result; } case j_break: { - delScope(localScope); + delScope(localScope); runtimeError("break outside of a loop or switch"); } case j_continue: { - delScope(localScope); + delScope(localScope); runtimeError("continue outside of a loop"); } case j_throw: { untrace(ast); - delScope(localScope); + delScope(localScope); oop res= jbs->result; jbRecPop(); jbs->result= res; siglongjmp(jbs->jb, j_throw); } } + // oop tmpresult = treeCopyUnquoting(get(func, Function, body), localScope); // eval inside the quasiquote thing oop result= eval(localScope, get(func, Function, body)); untrace(ast); delScope(localScope); @@ -2942,11 +3000,11 @@ oop eval(oop scope, oop ast) oop obj = map_get(ast, rhs_symbol); return obj; } -#if 0 case t_Quasiquote: { oop obj = map_get(ast, rhs_symbol); - return expandUnquotes(scope, obj); + return treeCopyUnquoting(scope, obj); } +#if 0 case t_Unquote: { runtimeError("@ outside of `"); } @@ -3587,6 +3645,12 @@ oop prim_clone(oop scope, oop params) return null; } +oop prim_treeCopy(oop scope, oop params) +{ + if (map_hasIntegerKey(params, 0)) return treeCopy(get(params, Map, elements)[0].value); + return null; +} + oop prim_print(oop scope, oop params) { assert(is(Map, params)); @@ -4061,6 +4125,7 @@ void outputNode(oop node) break; default: if (proto_number < t_C_declaration) { + println(node); outputNode(eval(globals, node)); break; } @@ -4736,9 +4801,11 @@ int main(int argc, char **argv) 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("treeCopy" ), makeFunction(prim_treeCopy, intern("treeCopy" ), null, null, globals, null)); map_set(globals, intern("import" ), makeFunction(prim_import, intern("import" ), null, null, globals, null)); map_set(globals, intern("microseconds"), makeFunction(prim_microseconds, intern("microseconds"), null, null, globals, null)); map_set(globals, intern("string" ), makeFunction(prim_String , intern("string" ), null, null, globals, null)); + map_set(globals, intern("scope" ), makeFunction(prim_scope, intern("scope" ), null, null, globals, null)); diff --git a/parsimonyLibrary/boot.mc b/parsimonyLibrary/boot.mc index f6b6b4a..19d414b 100644 --- a/parsimonyLibrary/boot.mc +++ b/parsimonyLibrary/boot.mc @@ -1,18 +1,19 @@ @{ println(x) { print(x, "\n"); } - treeCopy(x) { - l = {}; - k = _keys(x); - if (k == null) { - return clone(x); - } else { - for (i in k) { - l[k[i]] = clone(treeCopy(x[k[i]])); - } - return clone(l); - } - } + // now in C + // treeCopy(x) { + // l = {}; + // k = _keys(x); + // if (k == null) { + // return clone(x); + // } else { + // for (i in k) { + // l[k[i]] = clone(treeCopy(x[k[i]])); + // } + // return clone(l); + // } + // } //------------ creation C structure ------------// @@ -58,12 +59,34 @@ //-------------------- end ---------------------// + // Get the last element of s + last(s) { + s[length(s)-1]; + } // adding the element e at the end of the list l append(s, e) { s[length(s)] = e; } + push(s, e) { + append(s, e); + } + + pop(s, e) { + if (e == null) { + e = length(s) - 1 + } + ret = s[e]; + t = {}; + for (i in s) { + if (i == e) continue; + append(t, s[i]); + } + s = treeCopy(t); + ret; + } + // add or don't change an element in a dictionnary intern(s, e) { lo = 0; @@ -127,10 +150,6 @@ out; } - // Get the last element of s - last(s) { - s[length(s)-1]; - } nil; } diff --git a/parsimonyLibrary/dynamicObject.mc b/parsimonyLibrary/dynamicObject.mc index fc6e10e..624df77 100644 --- a/parsimonyLibrary/dynamicObject.mc +++ b/parsimonyLibrary/dynamicObject.mc @@ -99,12 +99,37 @@ struct Object { #define send(R, M, ...) ({ struct Object *__ = (struct Object *)(R); lookup(__->class, _selector_##M)(__, ##__VA_ARGS__); }) +struct __oop { int class; }; + +typedef struct __oop *oop; + @import("parsimonyLibrary/boot.mc") @{ + + rmSemi(x) { + x.semicolon = null; + x; + } + + makeln(x, tabs) { + x.semicolon.comment = newComment("\n"); + nbTabs = 0; + if (tabs != null) { nbTabs = tabs; } + for (i = 0; i0; i--) { @@ -145,15 +167,14 @@ struct Object { program.objects.function = "none"; return s; } +/*********** Method function ************/ if (program.objects.function == "method") { intern(program.objects.methods, string(program.last.declarators.declarators.identifier)); for (i in program.objects.class) { if (string(i) == string(program.objects.currentClassName)) intern(program.objects.class[i], string(program.last.declarators.declarators.identifier)); } program.last.declarators.declarators.identifier = string(program.objects.currentClassName) + "_" + string(program.last.declarators.declarators.identifier); - param = (`declaration struct __oop *__self; - ); - param.semicolon = null; + param = rmSemi(`declaration struct __oop *__self;); if (length(s.declarators.paramTypeL) > 0) { append(s.declarators.paramTypeL, newComma()); append(s.declarators.paramTypeL, treeCopy(param)); @@ -162,21 +183,19 @@ struct Object { s.declarators.paramTypeL[0] = treeCopy(param); } tmp = {}; - tmp[0] = (`declaration struct @@(newId(string(program.objects.currentClassName))) *self = (struct @@(newId(string(program.objects.currentClassName))) *) __self; - ); + // @@ problem for variable changement + tmp[0] = makeln(`declaration struct @@(newId(string(program.objects.currentClassName))) *self = (struct @@(newId(string(program.objects.currentClassName))) *) __self;, 1); s.compoundS.expression = treeCopy(fusion(tmp, s.compoundS.expression)); program.objects.function = "none"; return s; } +/*********** Constructor function ************/ if (program.objects.function == "constructor") { - structDeclaration = (`declaration struct @@(newId(string(program.objects.currentClassName))) *self = calloc(1, sizeof *self); - ); - rawDeclaration = (`declaration class = findClass(@@(newText("\"" + string(program.objects.currentClassName) + "\""))); - ); - returnSTMT = (`statement return (struct __oop *) self; -); + structDeclaration = makeln(`declaration struct @@(newId(string(program.objects.currentClassName))) *self = calloc(1, sizeof *self);, 1); + rawDeclaration = makeln(`declaration class = findClass(@@(newText("\"" + string(program.objects.currentClassName) + "\"")));, 1); + returnSTMT = makeln(`statement return (struct __oop *) self;); t = {}; - append(t, structDeclaration); + append(t, treeCopy(structDeclaration)); lhs = treeCopy(s.compoundS.expression[0].expression.lhs); lhs.rhs = rawDeclaration.declarators[0].lhs; rawDeclaration.declarators[0].lhs = lhs; @@ -186,11 +205,10 @@ struct Object { program.objects.function = "none"; return s; } +/*********** Main function ************/ if (s.declarators != null && s.declarators.declarators != null && string(s.declarators.declarators.identifier) == "main") { - rawSelector = (`declaration int _selector_ = findSelector("foo"); - ); - rawClass = (`declaration int _class_ = findClass("foo"); - ); + rawSelector = makeln(`declaration int _selector_ = findSelector("foo");, 1); + rawClass = makeln(`declaration int _class_ = findClass("foo");, 1); t = {}; for (i in program.objects.methods) { rawSelector.declarators[0].lhs.identifier = "_selector_" + string(program.objects.methods[i]); @@ -203,14 +221,13 @@ struct Object { rawClass.declarators[0].rhs.paramTypeL[0].text[0].value = "\"" + string(classKeys[i]) + "\""; append(t, treeCopy(rawClass)); } - rawAddMethod = (`declaration addMethod(_class_, _selector_, foo); - ); + rawAddMethod = makeln(`declaration addMethod(_class_, _selector_, foo);, 1); for (i in program.objects.class) { for (k in program.objects.class[i]) { newObject = treeCopy(rawAddMethod); newObject.declarators[0].paramTypeL[0].identifier = string(rawAddMethod.declarators[0].paramTypeL[0].identifier) + string(i); newObject.declarators[0].paramTypeL[2].identifier = string(rawAddMethod.declarators[0].paramTypeL[2].identifier) + string(program.objects.class[i][k]); - newObject.declarators[0].paramTypeL[4].identifier = string(i) + "_" + string(program.objects.class[i][k]); + newObject.declarators[0].paramTypeL[4].identifier = "(method_t) " + string(i) + "_" + string(program.objects.class[i][k]); append(t, treeCopy(newObject)); } } diff --git a/tests-parsimony/parsimony-lang/008.c b/tests-parsimony/parsimony-lang/008.c new file mode 100644 index 0000000..039f6da --- /dev/null +++ b/tests-parsimony/parsimony-lang/008.c @@ -0,0 +1,16 @@ +@{ + newText(x) { { value: x, __proto__: C_string }; } + + f(n) { + program.tmp = n; + `declaration int @@(newText(treeCopy(program.tmp)));; + } + + + f("x"); +} + +@{ + program.tmp = "y"; + nil; +} \ No newline at end of file diff --git a/tests-parsimony/parsimony-lang/008.out b/tests-parsimony/parsimony-lang/008.out new file mode 100644 index 0000000..4c2f455 --- /dev/null +++ b/tests-parsimony/parsimony-lang/008.out @@ -0,0 +1 @@ +int x; \ No newline at end of file diff --git a/tests-parsimony/parsimony-lang/009.c b/tests-parsimony/parsimony-lang/009.c new file mode 100644 index 0000000..818e2d6 --- /dev/null +++ b/tests-parsimony/parsimony-lang/009.c @@ -0,0 +1,10 @@ +@{ + newText(x) { { value: x, __proto__: C_string }; } + + f(n) { + `declaration int @@(newText(treeCopy(n)));; + } + + + f("x"); +} \ No newline at end of file diff --git a/tests-parsimony/parsimony-lang/009.out b/tests-parsimony/parsimony-lang/009.out new file mode 100644 index 0000000..4c2f455 --- /dev/null +++ b/tests-parsimony/parsimony-lang/009.out @@ -0,0 +1 @@ +int x; \ No newline at end of file diff --git a/tests-parsimony/realObject.c b/tests-parsimony/realObject.c index 73904ee..0a44e12 100644 --- a/tests-parsimony/realObject.c +++ b/tests-parsimony/realObject.c @@ -2,26 +2,21 @@ #include -struct __oop { int class; }; - -typedef struct __oop *oop; - @class struct Point { double x, y; }; - @constructor("Point") oop newPoint(double x, double y) { self->x = x; self->y = y; } -@method("Point") double magnitude() +@method("Point") double magnitude(int x) { printf("point method : %f\n", sqrt(self->x * self->x * self->y * self->y)); return sqrt(self->x * self->x * self->y * self->y); } -@method("Point") double getX() +@method("Point") double getX(int y) { printf("point method : %f\n", self->x); return self->x; @@ -32,6 +27,8 @@ int main() oop p = newPoint(3, 4); @send("p", "magnitude"); + + @send("p", "getX"); return 0; }