@(import("parsimonyLibrary/boot.mc")) @{ checkIdorDecl(x) { (x.identifier == null) ? x.declarators.identifier : x.identifier; } checkIdorText(x) { (x.identifier == null) ? x.text : x.identifier; } object(x) { x == null ? x = "oop" : x; program.objects.elements[length(program.objects.elements)] = x; program.objects.last = x; l = {}; enum = `declaration typedef enum {_} type_t;; enum.semicolon.comment = getComment("\n"); append(l, enum); obj = `declaration union object;; obj.semicolon.comment = getComment("\n"); append(l, treeCopy(obj)); type_obj = `declaration typedef union object *oop;; type_obj.declarators[0].declarators.identifier = clone(x); type_obj.semicolon.comment = getComment("\n"); append(l, treeCopy(type_obj)); l; } addObject() { enum = treeCopy(getEnum(program.last.name.identifier)); l = length(program.enums.last.enumList); if (string(program.enums.last.enumList[0].name.identifier) == "_" && l == 1) { program.enums.last.enumList[0] = enum; } else { append(program.enums.last.enumList, getComma()); append(program.enums.last.enumList, enum); } for (i=length(program.last.declarationL); i>0; i--) { program.last.declarationL[i] = program.last.declarationL[i-1]; }; newType = `declaration type_t type;; newType.semicolon.comment = getComment("\n "); program.last.declarationL[0] = treeCopy(newType); nil; } getObjectMacro() { macro = `ed #define get(PTR, TYPE, FIELD) (_checkType(PTR, TYPE, __FILE__, __LINE__)->TYPE.FIELD) ; macro; } setObjectMacro() { macro = `ed #define set(PTR, TYPE, FIELD, VALUE) (_checkType(PTR, TYPE, __FILE__, __LINE__)->TYPE.FIELD = VALUE) ; macro; } getGeneralObject(x) { func = `fun int getfoo(int obj) { if (!isFoo(obj)) { fprintf(stderr, "\ngetFoo call on non-foo\n"); exit(1); } return get(obj, foo, foo); } ; id = program.structs[x].declarationL[1].specifiers[0].identifier; star = program.structs[x].declarationL[1].declarators[0].declarators.star; if (id != null) { program.structs[x].declarationL[1].specifiers[0].text = program.structs[x].declarationL[1].specifiers[0].identifier } if (star != null) { func.specifiers[0].text = string(checkIdorText(program.structs[x].declarationL[1].specifiers[0])) + " *"; func.specifiers[0].comment = ""; } else { func.specifiers[0].text = string(checkIdorText(program.structs[x].declarationL[1].specifiers[0])); } func.declarators.declarators.identifier = "get" + string(x); func.compoundS.expression[0].condition.expression.declarators.identifier = "is" + string(x); func.compoundS.expression[0].consequent.expression[0].expression.paramTypeL[2].text[0].value = "\"\\nget" + string(x) + " call on non-" + string(x) + "\\n\""; func.compoundS.expression[1].expression.paramTypeL[2].identifier = string(x); func.compoundS.expression[1].expression.paramTypeL[4].identifier = checkIdorDecl(program.structs[x].declarationL[length(program.structs[x].declarationL)-1].declarators[0].declarators); func.declarators.paramTypeL[0].specifiers[0].text = program.objects.last; treeCopy(func); } // makeGeneralObject(x) { // func = `fun int makeString(int value) // { // oop newString = malloc(sizeof(struct String)); // newString->type = String; // } // ; // func.declarators.declarators.identifier = "make" + string(x); // func.specifiers[0].text = program.objects.last; // star = program.structs[x].declarationL[1].declarators[0].declarators.star; // if (star != null) { // func.declarators.paramTypeL[0].specifiers[0].text = string(checkIdorText(program.structs[x].declarationL[1].specifiers[0])) + " *"; // func.declarators.paramTypeL[0].specifiers[0].comment = ""; // } else { // func.declarators.paramTypeL[0].specifiers[0].text = string(checkIdorText(program.structs[x].declarationL[1].specifiers[0])); // } // func.compoundS.expression[0].declarators[0].lhs.identifier = "new" + string(x); // func.compoundS.expression[0].declarators[0].rhs.paramTypeL[0].typeName.specifiers[0].name.identifier = string(x); // func.compoundS.expression[1].expression.rhs.identifier = string(x); // func.compoundS.expression[1].expression.lhs.lhs.identifier = "new" + string(x); // for (i in program.structs[x].declarationL) { // if (i == 0) { continue; } // println(program.structs[x].declarationL[i]); // } // // println(func.compoundS.expression[1]); // treeCopy(func); // } endObject() { l = {}; objectUnion = `declaration union object { type_t type; };; objectUnion.semicolon.comment = getComment("\n"); obj = select(notToken, program.enums.last.enumList); elt = treeCopy(`declaration struct nil nil;); for (i in obj) { len = length(objectUnion.specifiers[0].declarationL); elt.specifiers[0].name.identifier = elt.declarators[0].identifier = obj[i].name.identifier; objectUnion.specifiers[0].declarationL[len] = treeCopy(elt); objectUnion.specifiers[0].declarationL[len].semicolon.comment = getComment(" "); } append(l, objectUnion); isDef = `declaration int is(type_t type, int obj);; isDef.declarators[0].paramTypeL[2].specifiers[0].text = program.objects.last; isDef.semicolon.comment = getComment("\n"); append(l, isDef); func = `fun int isFoo(int obj) { return is(foo, obj); }; func.declarators.paramTypeL[0].specifiers[0].text = program.objects.last; func.compoundS.rightCurly.comment = getComment("\n"); for (i in obj) { func.declarators.declarators.identifier = "is" + string(obj[i].name.identifier); func.compoundS.expression[0].expression.paramTypeL[0].identifier = obj[i].name.identifier; append(l, treeCopy(func)); } func = `fun type_t getType(int ptr) { assert(ptr); return ptr->type; }; func.declarators.paramTypeL[0].specifiers[0].text = program.objects.last; func.compoundS.rightCurly.comment = getComment("\n"); append(l, treeCopy(func)); func = `fun int is(type_t type, int obj) { return type == getType(obj); }; func.declarators.paramTypeL[2].specifiers[0].text = program.objects.last; func.compoundS.rightCurly.comment = getComment("\n"); append(l, treeCopy(func)); append(l, treeCopy(getObjectMacro())); append(l, treeCopy(setObjectMacro())); for (i in program.unions.last.declarationL) { if (i == 0) { continue; } func = getGeneralObject(program.unions.last.declarationL[i].specifiers[0].name.identifier); append(l, func); // func = makeGeneralObject(program.unions.last.declarationL[i].specifiers[0].name.identifier); // append(l, func); } l; } nil; }