Mercurial > repos > rhope
changeset 34:df038cef648b
More work on supporting user defined types in the C backend
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 30 Sep 2009 01:25:03 -0400 |
parents | 3b47a8538df2 |
children | 3498713c3dc9 |
files | cbackend.rhope nworker.rhope runtime/object.c runtime/object.h |
diffstat | 4 files changed, 233 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/cbackend.rhope Mon Sep 28 22:08:40 2009 -0400 +++ b/cbackend.rhope Wed Sep 30 01:25:03 2009 -0400 @@ -57,6 +57,35 @@ out,notfound <- [[reg]Lookup >>]Index[method] } +Blueprint C Field Registry +{ + Lookup + Next ID +} + +C Field Registry[:out] +{ + out <- [[Build["C Field Registry"]]Lookup <<[New@Dictionary[]]]Next ID<<[0] + +} + +Register Field@C Field Registry[reg,field:out] +{ + [[reg]Lookup >>]Index[field] + { + out <- reg + }{ + field ID <- [reg]Next ID>> + new lookup <- [[reg]Lookup >>]Set[field, field ID] + out <- [[reg]Lookup <<[new lookup]]Next ID <<[[field ID]+[1]] + } +} + +Field ID@C Field Registry[reg,field:out,notfound] +{ + out,notfound <- [[reg]Lookup >>]Index[field] +} + Blueprint C Type { Name @@ -79,16 +108,36 @@ out <- [ctype]Methods <<[ [[ctype]Methods >>]Append[name] ] } +Register Methods@C Type[ctype,method reg:out] +{ + out <- Fold["Register Method", method reg, [ctype]Methods >>] +} + +Register Fields@C Type[ctype,field reg:out] +{ + out <- Fold["Register Field", field reg, [ctype]Fields >>] +} + +Rhope Type to C[typename,naked:out] +{ + If[[typename] = ["Any Type"]] + { + ctype <- "struct object" + }{ + ctype <- ["t_"]Append[Escape Rhope Name[typename]] + } + If[naked] + { + out <- Val[ctype] + }{ + out <- [ctype]Append[" * "] + } +} + _Type Def C Type[text,field:out] { name <- [field]Index[0] - rawtype <- [field]Index[1] - If[[rawtype] = ["Any Type"]] - { - type <- "\n\tobject * " - }{ - type <- [["\n\tt_"]Append[Escape Rhope Name[rawtype]]]Append[" * "] - } + type <- ["\n\t"]Append[Rhope Type to C[[field]Index[1], No]] out <- [[[text]Append[type]]Append[Escape Rhope Name[name]]]Append[";"] } @@ -140,8 +189,29 @@ ]Next ID <<[0] } -Register Type@C Type Registry[reg,name,def:out] +_Type Defs C[text,def:out] +{ + out <- [[text]Append["\n\n"]]Append[[def]Type Def] +} + +Type Defs@C Type Registry[reg:out] +{ + out <- Fold["_Type Defs C", "", [reg]Definitions >>] +} + +_Type Inits C[reg,method reg,field reg,text,def,name:out] { + out <- [[text]Append["\n\n"]]Append[ [def]Type Init[[reg]Type ID[name], method reg, field reg] ] +} + +Type Inits@C Type Registry[reg,method reg,field reg:out] +{ + out <- Fold[[[["_Type Inits C"]Set Input[0, reg]]Set Input[1, method reg]]Set Input[2, field reg], "", [reg]Definitions >>] +} + +Register Type@C Type Registry[reg,def:out] +{ + name <- [def]Name >> [[reg]Lookup >>]Index[name] { out <- reg @@ -418,26 +488,32 @@ Text@C Function[func:out] { cname <- Escape Rhope Name[[func]Name >>] - If[ [[[func]Variables >>]Length] = [0] ] + If[ [[func]Convention >>] = ["rhope"] ] { - out <- [[[[[["FuncNoLocals(" - ]Append[cname] - ]Append[",\n\tNumParams "] - ]Append[ [[func]Inputs >>]Length ] - ]Append[",\n\tCallSpace 32)\n\n"]//TODO: Fill in with calculated callspace value - ]Append[ [[func]Statements >>]Join[""] ] - ]Append["EndFunc"] + If[ [[[func]Variables >>]Length] = [0] ] + { + out <- [[[[[["FuncNoLocals(" + ]Append[cname] + ]Append[",\n\tNumParams "] + ]Append[ [[func]Inputs >>]Length ] + ]Append[",\n\tCallSpace 32)\n\n"]//TODO: Fill in with calculated callspace value + ]Append[ [[func]Statements >>]Join[""] ] + ]Append["EndFunc"] + }{ + out <- [[[[[[[[["Func(" + ]Append[cname] + ]Append[",\n\tNumParams "] + ]Append[ [[func]Inputs >>]Length ] + ]Append[",\n\tCallSpace 32,\n\t"]//TODO: Fill in with calculated callspace value + ]Append[["l_"]Append[cname]] + ]Append[")\n\n"] + ]Append[ [[func]Statements >>]Join[""] ] + ]Append[[func]Set Outputs] + ]Append["EndFunc"] + } }{ - out <- [[[[[[[[["Func(" - ]Append[cname] - ]Append[",\n\tNumParams "] - ]Append[ [[func]Inputs >>]Length ] - ]Append[",\n\tCallSpace 32,\n\t"]//TODO: Fill in with calculated callspace value - ]Append[["l_"]Append[cname]] - ]Append[")\n\n"] - ]Append[ [[func]Statements >>]Join[""] ] - ]Append[[func]Set Outputs] - ]Append["EndFunc"] + //TODO: We need to store input and output types somewhere so we can reference them here + out <- "oops" } } @@ -445,11 +521,25 @@ { Functions Method Registry + Field Registry + Type Registry } C Program[:out] { - out <- [[Build["C Program"]]Functions <<[New@Dictionary[]]]Method Registry <<[C Method Registry[]] + out <- [[[[Build["C Program"]]Functions <<[New@Dictionary[]]]Method Registry <<[C Method Registry[]]]Type Registry <<[C Type Registry[]]]Field Registry <<[C Field Registry[]] +} + +Register Type@C Program[program,def:out] +{ + out <- [[[program]Type Registry <<[ [[program]Type Registry >>]Register Type[def] ] + ]Method Registry <<[ [def]Register Methods[[program]Method Registry >>] ] + ]Field Registry <<[ [def]Register Fields[[program]Field Registry >>] ] +} + +Create Type@C Program[program,name:out] +{ + out <- C Type[name] } Create Function@C Program[program,name,inputs,outputs,convention:out] @@ -508,7 +598,9 @@ #include \"context.h\" #include \"func.h\" #include \"integer.h\"\n\n" - out <- [[[[headers]Append[Fold["_Text C Program", + out <- [[[[[[headers + ]Append[[[program]Type Registry >>]Type Defs] + ]Append[Fold["_Text C Program", Fold["_Consts C Program", Fold["_Defs C Program", "", [program]Functions >>], constants @@ -519,6 +611,7 @@ calldata *cdata; context * ct; register_builtin_types();\n\n"] + ]Append[ [[program]Type Registry >>]Type Inits[[program]Method Registry >>, [program]Field Registry >>] ] ]Append[Fold["_Set Consts C Program", "", constants]] ]Append[" ct = new_context();
--- a/nworker.rhope Mon Sep 28 22:08:40 2009 -0400 +++ b/nworker.rhope Wed Sep 30 01:25:03 2009 -0400 @@ -654,9 +654,9 @@ Test[:out] { - ref+ <- Worker Ref["+","cdecl",2,1] - ref* <- Worker Ref["*","cdecl",2,1] - ,a <- [NWorker["cdecl"] + ref+ <- Worker Ref["+","rhope",2,1] + ref* <- Worker Ref["*","rhope",2,1] + ,a <- [NWorker["rhope"] ]Add Input["a", 0] { ,b <- [~]Add Input["b", 1] { ,c <- [~]Add Input["c", 2] { @@ -716,15 +716,15 @@ Register Builtins@NProgram[prog:out] { - out <- [[[[[[[[[prog]Register Worker["+", "cdecl", 2, 1] - ]Register Worker["-", "cdecl", 2, 1] - ]Register Worker["*", "cdecl", 2, 1] - ]Register Worker["/", "cdecl", 2, 1] - ]Register Worker["Print", "cdecl", 1, 1] - ]Register Worker["Index", "cdecl", 2, 1] - ]Register Worker["If", "cdecl", 1, 2] - ]Register Worker["<", "cdecl", 2, 1] - ]Register Worker["<String@Whole Number", "cdecl", 1, 1] + out <- [[[[[[[[[prog]Register Worker["+", "rhope", 2, 1] + ]Register Worker["-", "rhope", 2, 1] + ]Register Worker["*", "rhope", 2, 1] + ]Register Worker["/", "rhope", 2, 1] + ]Register Worker["Print", "rhope", 1, 1] + ]Register Worker["Index", "rhope", 2, 1] + ]Register Worker["If", "rhope", 1, 2] + ]Register Worker["<", "rhope", 2, 1] + ]Register Worker[">", "rhope", 1, 1] } Find Worker@NProgram[prog, name:out,notfound]
--- a/runtime/object.c Mon Sep 28 22:08:40 2009 -0400 +++ b/runtime/object.c Wed Sep 30 01:25:03 2009 -0400 @@ -342,6 +342,104 @@ bp->method_lookup[methodid-bp->first_methodid] = impl; } +void add_getter(blueprint * bp, uint32_t getfieldid, rhope_func impl) +{ + rhope_func * temp; + if(getfieldid < 1) { + fputs("Attempt to add a method with an ID < 1\n", stderr); + exit(-1); + } + if (!bp->getter_lookup) + { + bp->getter_lookup = malloc(sizeof(rhope_func) * INITIAL_METHOD_LOOKUP); + if(!bp->getter_lookup) { + fprintf(stderr, "Couldn't allocate %d bytes for getter lookup table\n", sizeof(rhope_func) * INITIAL_METHOD_LOOKUP); + exit(-1); + } + if(BELOW_INITIAL_METHOD > getfieldid) { + bp->first_getfieldid = 1; + bp->last_getfieldid = 1+INITIAL_METHOD_LOOKUP; + } else { + bp->first_getfieldid = getfieldid - BELOW_INITIAL_METHOD; + bp->last_getfieldid = bp->first_getfieldid + INITIAL_METHOD_LOOKUP; + } + memset(bp->getter_lookup, '\0', sizeof(rhope_func) * INITIAL_METHOD_LOOKUP); + } else { + if (getfieldid < bp->first_getfieldid) { + temp = bp->getter_lookup; + //Note: if this gets changed to generating an exception on failure, we need to restore the original buffer + bp->getter_lookup = malloc(sizeof(rhope_func) * (bp->last_getfieldid-getfieldid)); + if(!bp->getter_lookup) { + fprintf(stderr, "Couldn't allocate %d bytes for getter lookup table\n", sizeof(rhope_func) * (bp->last_getfieldid-getfieldid)); + exit(-1); + } + memset(bp->getter_lookup, '\0', (bp->first_getfieldid-getfieldid) * sizeof(rhope_func)); + memcpy(bp->getter_lookup + bp->first_getfieldid-getfieldid, temp, (bp->last_getfieldid-bp->first_getfieldid)*sizeof(rhope_func)); + free(temp); + bp->first_getfieldid = getfieldid; + } else if(getfieldid >= bp->last_getfieldid) { + //Note: if this gets changed to generating an exception on failure, we need to restore the original buffer + bp->getter_lookup = realloc(bp->getter_lookup, (getfieldid+1-bp->first_getfieldid) * sizeof(rhope_func)); + if(!bp->getter_lookup) { + fprintf(stderr, "Couldn't resize getter lookup table to %d bytes\n", (getfieldid+1-bp->first_getfieldid) * sizeof(rhope_func)); + exit(-1); + } + memset(bp->getter_lookup+bp->last_getfieldid, '\0', (getfieldid+1)-bp->last_getfieldid); + bp->last_getfieldid = getfieldid+1; + } + } + bp->getter_lookup[getfieldid-bp->first_getfieldid] = impl; +} + +void add_setter(blueprint * bp, uint32_t setfieldid, rhope_func impl) +{ + rhope_func * temp; + if(setfieldid < 1) { + fputs("Attempt to add a method with an ID < 1\n", stderr); + exit(-1); + } + if (!bp->setter_lookup) + { + bp->setter_lookup = malloc(sizeof(rhope_func) * INITIAL_METHOD_LOOKUP); + if(!bp->setter_lookup) { + fprintf(stderr, "Couldn't allocate %d bytes for setter lookup table\n", sizeof(rhope_func) * INITIAL_METHOD_LOOKUP); + exit(-1); + } + if(BELOW_INITIAL_METHOD > setfieldid) { + bp->first_setfieldid = 1; + bp->last_setfieldid = 1+INITIAL_METHOD_LOOKUP; + } else { + bp->first_setfieldid = setfieldid - BELOW_INITIAL_METHOD; + bp->last_setfieldid = bp->first_setfieldid + INITIAL_METHOD_LOOKUP; + } + memset(bp->setter_lookup, '\0', sizeof(rhope_func) * INITIAL_METHOD_LOOKUP); + } else { + if (setfieldid < bp->first_setfieldid) { + temp = bp->setter_lookup; + //Note: if this sets changed to generating an exception on failure, we need to restore the original buffer + bp->setter_lookup = malloc(sizeof(rhope_func) * (bp->last_setfieldid-setfieldid)); + if(!bp->setter_lookup) { + fprintf(stderr, "Couldn't allocate %d bytes for setter lookup table\n", sizeof(rhope_func) * (bp->last_setfieldid-setfieldid)); + exit(-1); + } + memset(bp->setter_lookup, '\0', (bp->first_setfieldid-setfieldid) * sizeof(rhope_func)); + memcpy(bp->setter_lookup + bp->first_setfieldid-setfieldid, temp, (bp->last_setfieldid-bp->first_setfieldid)*sizeof(rhope_func)); + free(temp); + bp->first_setfieldid = setfieldid; + } else if(setfieldid >= bp->last_setfieldid) { + //Note: if this sets changed to generating an exception on failure, we need to restore the original buffer + bp->setter_lookup = realloc(bp->setter_lookup, (setfieldid+1-bp->first_setfieldid) * sizeof(rhope_func)); + if(!bp->setter_lookup) { + fprintf(stderr, "Couldn't resize setter lookup table to %d bytes\n", (setfieldid+1-bp->first_setfieldid) * sizeof(rhope_func)); + exit(-1); + } + memset(bp->setter_lookup+bp->last_setfieldid, '\0', (setfieldid+1)-bp->last_setfieldid); + bp->last_setfieldid = setfieldid+1; + } + } + bp->setter_lookup[setfieldid-bp->first_setfieldid] = impl; +} + blueprint * get_blueprint_byid(uint32_t type) { if(type >= max_registered_type)
--- a/runtime/object.h Mon Sep 28 22:08:40 2009 -0400 +++ b/runtime/object.h Wed Sep 30 01:25:03 2009 -0400 @@ -71,6 +71,8 @@ blueprint * register_type_byid(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup); blueprint * new_blueprint(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup); void add_method(blueprint * bp, uint32_t methodid, rhope_func impl); +void add_getter(blueprint * bp, uint32_t fieldid, rhope_func impl); +void add_setter(blueprint * bp, uint32_t fieldid, rhope_func impl); returntype convert_to(uint32_t convertto, calldata * params); returntype convert_from(uint32_t convertfrom, calldata * params); object * copy_object(object * tocopy);