Explorar el Código

Switch between C & Parsimony fix

develop-theo
Theo Souchon hace 2 años
padre
commit
0df1d03e90
Se han modificado 8 ficheros con 218 adiciones y 90 borrados
  1. +110
    -43
      ccmeta.leg
  2. +35
    -16
      parsimonyLibrary/boot.mc
  3. +41
    -24
      parsimonyLibrary/dynamicObject.mc
  4. +16
    -0
      tests-parsimony/parsimony-lang/008.c
  5. +1
    -0
      tests-parsimony/parsimony-lang/008.out
  6. +10
    -0
      tests-parsimony/parsimony-lang/009.c
  7. +1
    -0
      tests-parsimony/parsimony-lang/009.out
  8. +4
    -7
      tests-parsimony/realObject.c

+ 110
- 43
ccmeta.leg Ver fichero

@ -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<get(obj, Map, size); i++) {
elements[i].value = treeCopy(elements[i].value);
}
set(map, Map, elements, elements);
return map;
}
}
return obj;
}
oop treeCopyUnquoting(oop scope, 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<get(obj, Map, size); i++) {
int firstCond = is(Map, elements[i].value) && map_get(elements[i].value, __proto___symbol) != null;
if (firstCond && get(map_get(map_get(elements[i].value, __proto___symbol), __name___symbol), Symbol, prototype) < t_Comment) {
elements[i].value = eval(scope, treeCopyUnquoting(scope, elements[i].value));
} else {
elements[i].value = treeCopyUnquoting(scope, elements[i].value);
}
}
set(map, Map, elements, elements);
return map;
}
}
return obj;
}
%}
#--------------------------------------------- C grammar -------------------------------------------------#
@ -1385,7 +1465,7 @@ id = { $$= 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 = <NAME> &{ !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));

+ 35
- 16
parsimonyLibrary/boot.mc Ver fichero

@ -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;
}

+ 41
- 24
parsimonyLibrary/dynamicObject.mc Ver fichero

@ -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; i<tabs; i++) {
x.semicolon.comment.text = string(x.semicolon.comment.text) + " ";
}
x;
}
program.objects = {};
program.objects.class = {};
program.objects.methods = {};
program.objects.send = {};
program.objects.send.object = {};
program.objects.send.method = {};
sendLen = -1;
sw = 0;
class()
{
@ -127,15 +152,12 @@ struct Object {
send(object, method)
{
rawSend = (`declaration send(obj, met););
rawSend.semicolon = null;
rawSend.declarators[0].paramTypeL[0].identifier = object;
rawSend.declarators[0].paramTypeL[2].identifier = method;
treeCopy(rawSend);
treeCopy(rmSemi(`declaration send(@@(newText(object)), @@(newText(method)));));
}
everyExternalDeclaration(s)
{
/*********** Class function ************/
if (program.objects.function == "class") {
program.objects.class[program.last.name.identifier] = {};
for (i=length(program.last.declarationL); i>0; 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));
}
}

+ 16
- 0
tests-parsimony/parsimony-lang/008.c Ver fichero

@ -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;
}

+ 1
- 0
tests-parsimony/parsimony-lang/008.out Ver fichero

@ -0,0 +1 @@
int x;

+ 10
- 0
tests-parsimony/parsimony-lang/009.c Ver fichero

@ -0,0 +1,10 @@
@{
newText(x) { { value: x, __proto__: C_string }; }
f(n) {
`declaration int @@(newText(treeCopy(n)));;
}
f("x");
}

+ 1
- 0
tests-parsimony/parsimony-lang/009.out Ver fichero

@ -0,0 +1 @@
int x;

+ 4
- 7
tests-parsimony/realObject.c Ver fichero

@ -2,26 +2,21 @@
#include <math.h>
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;
}

Cargando…
Cancelar
Guardar