C compiler with embedded metalanguage.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

150 行
6.1 KiB

@import("parsimonyLibrary/boot.mc")
@{
checkIdorDecl(x) {
(x.identifier == null) ? x.declarators.identifier : x.identifier;
}
checkIdorText(x) {
(x.identifier == null) ? x.text : x.identifier;
}
program.objects = null;
beginObject(objectName, typeName) {
program.objects = {};
program.objects.elements = {};
program.objects.last = null;
objectName == null ? objectName = "oop" : objectName;
typeName == null ? typeName = "type_t" : typeName;
program.objects.elements[length(program.objects.elements)] = objectName;
program.objects.last = objectName;
l = {};
enum = `declaration typedef enum {_} type_t;;
enum.declarators[0].identifier = typeName;
enum.semicolon.comment = getComment(" ");
program.objects.enum = treeCopy(enum);
append(l, program.objects.enum);
obj = `declaration union object;;
obj.semicolon.comment = getComment(" ");
append(l, treeCopy(obj));
type_obj = `declaration typedef union object *oop;;
type_obj.declarators[0].declarators.identifier = objectName;
type_obj.semicolon.comment = getComment(" ");
append(l, treeCopy(type_obj));
l;
}
addObject() {
structName = treeCopy(getEnum(program.last.name.identifier));
l = length(program.enums.last.enumList);
if (string(program.objects.enum.specifiers[1].enumList[0].name.identifier) == "_" && l == 1) {
program.objects.enum.specifiers[1].enumList[0] = structName;
} else {
append(program.objects.enum.specifiers[1].enumList, getComma());
append(program.objects.enum.specifiers[1].enumList, structName);
}
for (i=length(program.last.declarationL); i>0; i--) {
program.last.declarationL[i] = program.last.declarationL[i-1];
};
newType = `declaration int type;;
newType.specifiers[0].text = program.objects.enum.declarators[0].identifier;
newType.semicolon.comment = getComment("\n ");
program.last.declarationL[0] = treeCopy(newType);
nil;
}
everyExternalDeclaration(s) {
if (program.objects) {
addObject()
}
s;
}
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);
}
endObject() {
l = {};
objectUnion = `declaration union object { int type; };;
objectUnion.specifiers[0].declarationL[0].specifiers[0].text = program.objects.enum.declarators[0].identifier;
objectUnion.semicolon.comment = getComment("\n");
obj = select(notToken, program.objects.enum.specifiers[1].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(int type, int obj);;
isDef.declarators[0].paramTypeL[0].specifiers[0].text = program.objects.enum.declarators[0].identifier;
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 int getType(int ptr) { assert(ptr); return ptr->type; };
func.specifiers[0].text = program.objects.enum.declarators[0].identifier;
func.declarators.paramTypeL[0].specifiers[0].text = program.objects.last;
func.compoundS.rightCurly.comment = getComment("\n");
append(l, treeCopy(func));
func = `fun int is(int type, int obj) { return type == getType(obj); };
func.declarators.paramTypeL[0].specifiers[0].text = program.objects.enum.declarators[0].identifier;
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()));
program.objects = null;
l;
}
nil;
}