diff --git a/src/ccmeta.leg b/src/ccmeta.leg index b65ca9e..4bacac4 100644 --- a/src/ccmeta.leg +++ b/src/ccmeta.leg @@ -1356,6 +1356,11 @@ oop ensure(int id, oop s) fprintf(stderr, "Meta expression did not return required Id\n"); exit(1); } + break; + } + default: { + fprintf(stderr, "ensure function: id not impleted"); + exit(1); } } } @@ -3764,6 +3769,22 @@ oop prim_parseFrom(oop scope, oop params) oop res = yyparsefrom(yy_declaration) ? __ : null ; yylval = res; // TODO return res; + } else if (!strcmp(s, "expression")) { + oop res = yyparsefrom(yy_expression) ? __ : null ; + yylval = res; // TODO + return res; + } else if (!strcmp(s, "statement")) { + oop res = yyparsefrom(yy_statement) ? __ : null ; + yylval = res; // TODO + return res; + } else if (!strcmp(s, "id")) { + oop res = yyparsefrom(yy_id) ? __ : null ; + yylval = res; // TODO + return res; + } else if (!strcmp(s, "func")) { + oop res = yyparsefrom(yy_functionDefinition) ? __ : null ; + yylval = res; // TODO + return res; } printf("%s expected\n", s); return null; diff --git a/src/parsimonyLibrary/dynamicObjectParsFrom.mc b/src/parsimonyLibrary/dynamicObjectParsFrom.mc index ea70d2b..4e4452b 100644 --- a/src/parsimonyLibrary/dynamicObjectParsFrom.mc +++ b/src/parsimonyLibrary/dynamicObjectParsFrom.mc @@ -19,8 +19,6 @@ struct Symbol *newSymbol(char *name) struct Symbol **symbols = 0; int nSymbols = 0; - - struct Symbol *intern(char *name) { int lo = 0; @@ -147,19 +145,57 @@ typedef struct __oop *oop; exp; } - method(object_name) + method() { - program.objects.currentClassName = object_name; - program.objects.function = "method"; + id = string(parseFrom("id").identifier); + decl = parseFrom("func"); + intern(program.objects.methods, decl.declarators.declarators.identifier); + for (i in program.objects.class) { + if (string(i) == id) intern(program.objects.class[i], decl.declarators.declarators.identifier); + } + decl.declarators.declarators.identifier = id + "_" + string(decl.declarators.declarators.identifier); + param = rmSemi(`declaration struct __oop *__self;); + if (length(decl.declarators.paramTypeL) > 0) { + append(decl.declarators.paramTypeL, newComma()); + append(decl.declarators.paramTypeL, treeCopy(param)); + } else { + decl.declarators.paramTypeL = {}; + decl.declarators.paramTypeL[0] = treeCopy(param); + } + tmp = {}; + tmp[0] = makeln(`declaration struct @@(newId(id, " ")) *self = (struct @@(newId(id, " ")) *) __self;, 1); + decl.compoundS.expression = treeCopy(fusion(tmp, decl.compoundS.expression)); + program.objects.function = "none"; nil; } - constructor(object_name) { - program.objects.currentClassName = object_name; - program.objects.function = "constructor"; + constructor() { + id = string(parseFrom("id").identifier); + decl = parseFrom("func"); + rawDeclaration = makeln(`declaration class = findClass(@@(newText("\"" + id + "\"")));, 1); + t = {}; + append(t, treeCopy(makeln(`declaration struct @@(newId(id, " ")) *self = calloc(1, sizeof *self);, 1))); + // take the structure of self->foo + lhs = treeCopy(decl.compoundS.expression[0].expression.lhs); + lhs.rhs = newId("class", " "); + // Change foo to Class + rawDeclaration.declarators[0].lhs = lhs; + // prepare the right object to return + append(decl.compoundS.expression, rawDeclaration); + append(decl.compoundS.expression, makeln(`statement return (struct __oop *) self;)); + decl.compoundS.expression = fusion(t, decl.compoundS.expression); + program.objects.function = "none"; nil; } + send2() + { + object = string(parseFrom("id").identifier); + method = parseFrom("declaration"); + // treeCopy(rmSemi(`declaration send(@@(newText(object)), @@(newText(method)));)); + nil; + } + send(object, method) { treeCopy(rmSemi(`declaration send(@@(newText(object)), @@(newText(method)));)); @@ -167,54 +203,6 @@ typedef struct __oop *oop; 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--) { - program.last.declarationL[i] = program.last.declarationL[i-1]; - }; - program.last.declarationL[0] = treeCopy(`declaration int class; ); - program.objects.function = "none"; - return s; - } -/*********** Method function ************/ - if (program.objects.function == "method") { - intern(program.objects.methods, program.last.declarators.declarators.identifier); - for (i in program.objects.class) { - if (string(i) == program.objects.currentClassName) intern(program.objects.class[i], program.last.declarators.declarators.identifier); - } - program.last.declarators.declarators.identifier = program.objects.currentClassName + "_" + string(program.last.declarators.declarators.identifier); - param = rmSemi(`declaration struct __oop *__self;); - if (length(s.declarators.paramTypeL) > 0) { - append(s.declarators.paramTypeL, newComma()); - append(s.declarators.paramTypeL, treeCopy(param)); - } else { - s.declarators.paramTypeL = {}; - s.declarators.paramTypeL[0] = treeCopy(param); - } - tmp = {}; - tmp[0] = makeln(`declaration struct @@(newId(program.objects.currentClassName, " ")) *self = (struct @@(newId(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") { - rawDeclaration = makeln(`declaration class = findClass(@@(newText("\"" + program.objects.currentClassName + "\"")));, 1); - t = {}; - append(t, treeCopy(makeln(`declaration struct @@(newId(program.objects.currentClassName, " ")) *self = calloc(1, sizeof *self);, 1))); - // take the structure of self->foo - lhs = treeCopy(s.compoundS.expression[0].expression.lhs); - lhs.rhs = newId("class", " "); - // Change foo to Class - rawDeclaration.declarators[0].lhs = lhs; - // prepare the right object to return - append(s.compoundS.expression, rawDeclaration); - append(s.compoundS.expression, makeln(`statement return (struct __oop *) self;)); - s.compoundS.expression = fusion(t, s.compoundS.expression); - program.objects.function = "none"; - return s; - } /*********** Main function ************/ if (s.declarators != null && s.declarators.declarators != null && string(s.declarators.declarators.identifier) == "main") { t = {}; diff --git a/src/tests/tests-parsimony/realObjectPF.c b/src/tests/tests-parsimony/realObjectPF.c new file mode 100644 index 0000000..59c7c05 --- /dev/null +++ b/src/tests/tests-parsimony/realObjectPF.c @@ -0,0 +1,34 @@ +@import("parsimonyLibrary/dynamicObjectParsFrom.mc") + +#include + +@class struct Point { double x, y; }; + +@constructor Point oop newPoint(double x, double y) +{ + self->x = x; + self->y = y; +} + +@method Point double magnitude() +{ + 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() +{ + printf("point method : %f\n", self->x); + return self->x; +} + +int main() +{ + oop p = newPoint(3, 4); + + @send("p", "magnitude"); + + @send("p", "getX"); + + return 0; +} \ No newline at end of file diff --git a/src/tests/tests-parsimony/realObjectPF.out b/src/tests/tests-parsimony/realObjectPF.out new file mode 100644 index 0000000..29dc8d5 --- /dev/null +++ b/src/tests/tests-parsimony/realObjectPF.out @@ -0,0 +1,145 @@ +#include +#include +#include + +struct Symbol { + char *name; + int class, selector; +}; + +struct Symbol *newSymbol(char *name) +{ + struct Symbol *symbol = malloc(sizeof(*symbol)); + symbol->name = strdup(name); + symbol->class = 0; + symbol->selector = 0; + return symbol; +} + +struct Symbol **symbols = 0; +int nSymbols = 0; + +struct Symbol *intern(char *name) +{ + int lo = 0; + int hi = nSymbols - 1; + while (lo <= hi ) { + int mid = (lo+hi)/2; + int cmp = strcmp(name, symbols[mid]->name); + if (cmp > 0) lo = mid + 1; + else if (cmp < 0) hi = mid - 1; + else return symbols[mid]; + } + symbols = realloc(symbols, sizeof(*symbols) * ++nSymbols); + memmove(symbols + lo + 1, symbols + lo, sizeof(*symbols)*(nSymbols - lo - 1)); + return symbols[lo] = newSymbol(name); +} + +typedef void *(*method_t)(); + +void *method_dnu() +{ + printf("method not found\n"); + exit(1); + return 0; +} + +method_t **methods = 0; +int nClasses = 0; +int nSelectors = 0; + +int ensureClass(struct Symbol *symbol) +{ + if (symbol->class == 0) { + if (nClasses == 0) nClasses++; + symbol->class = nClasses++; + methods = realloc(methods, sizeof(*methods)*nClasses); + methods[symbol->class] = malloc(sizeof(*methods)*nSelectors); + for (int i = 0; iclass][i] = method_dnu; + } + return symbol->class; +} + +int ensureSelector(struct Symbol *symbol) +{ + if (symbol->selector == 0) { + if (nSelectors == 0) nSelectors++; + symbol->selector = nSelectors++; + for (int i = 0; iselector; +} + +int findClass(char *class) +{ + return ensureClass(intern(class)); +} + +int findSelector(char *selector) +{ + return ensureSelector(intern(selector)); +} + +void addMethod(int class, int selector, method_t method) +{ + methods[class][selector] = method; +} + +#define lookup(C, S) (methods[C][S]) + +struct Object { + int class; +}; + +#define send(R, M, ...) ({ struct Object *__ = (struct Object *)(R); lookup(__->class, _selector_##M)(__, ##__VA_ARGS__); }) + +struct __oop { int class; }; + +typedef struct __oop *oop; + +#include + +struct Point { int class; double x, y; }; + +oop newPoint(double x, double y) +{ + struct Point *self = calloc(1, sizeof *self); + self->x = x; + self->y = y; +self->class = findClass("Point"); + return (struct __oop *) self; +} + +double Point_magnitude(struct __oop *__self) +{ + struct Point *self = (struct Point *) __self; + printf("point method : %f\n", sqrt(self->x * self->x * self->y * self->y)); + return sqrt(self->x * self->x * self->y * self->y); +} + +double Point_getX(struct __oop *__self) +{ + struct Point *self = (struct Point *) __self; + printf("point method : %f\n", self->x); + return self->x; +} + +int main() +{ + int _selector_magnitude= findSelector("magnitude"); + int _selector_getX= findSelector("getX"); + int _class_Point= findClass("Point"); + addMethod(_class_Point, _selector_magnitude, (method_t) Point_magnitude); + addMethod(_class_Point, _selector_getX, (method_t) Point_getX); + oop p = newPoint(3, 4); + + send(p, magnitude); + + send(p, getX); + + return 0; +} \ No newline at end of file