From ccbc4b5e08e692cca543801c1ab0ace35dc4c596 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Fri, 28 Jun 2019 08:35:39 -0300 Subject: [PATCH] Use type codename for function naming --- nelua/cgenerator.lua | 2 +- nelua/typechecker.lua | 32 ++++++++++++++++++++++++-------- spec/05-cgenerator_spec.lua | 12 ++++++++++++ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/nelua/cgenerator.lua b/nelua/cgenerator.lua index a57ea9dd..b841ee01 100644 --- a/nelua/cgenerator.lua +++ b/nelua/cgenerator.lua @@ -67,7 +67,7 @@ local function visit_assignments(context, emitter, varnodes, valnodes, decl) decemitter:add('static ') end decemitter:add(varnode) - if valnode and valnode.attr.compconst then + if valnode and (valnode.attr.compconst or varattr.const or varattr.compconst) then -- initialize to const values decemitter:add(' = ') assert(not lastcallindex) diff --git a/nelua/typechecker.lua b/nelua/typechecker.lua index 26f78980..e8b00dd0 100644 --- a/nelua/typechecker.lua +++ b/nelua/typechecker.lua @@ -214,6 +214,10 @@ function visitors.Table(context, node, desiredtype) end function visitors.Pragma(context, node, symbol) + if symbol and node.attr.symbol == symbol then + -- quick return + return + end local name, argnodes = node:args() context:traverse(argnodes) @@ -283,6 +287,7 @@ function visitors.Pragma(context, node, symbol) if name == 'strict' then config.strict = true end + node.attr.symbol = symbol end function visitors.Id(context, node) @@ -1074,16 +1079,31 @@ function visitors.VarDecl(context, node) end if valtype then varnode:assertraisef(not valtype:is_void(), 'cannot assign to expressions of type void') + local foundtype = false if varnode.attr.compconst then -- for consts the type must be known ahead - vartype = valtype - symbol.attr.type = valtype + foundtype = true symbol.attr.value = valnode.attr.value elseif valtype:is_type() then -- for 'type' types the type must also be known ahead - vartype = valtype - symbol.attr.type = valtype + assert(valnode and valnode.attr.holdedtype) + foundtype = true symbol.attr.compconst = true + symbol.attr.holdedtype = valnode.attr.holdedtype + end + + if foundtype then + if vartype ~= valtype then + assert(not vartype) + vartype = valtype + symbol.attr.type = valtype + + local pragmanode = varnode[4] + if pragmanode then + -- must retravese pragma node early once type is found ahead + context:traverse(pragmanode, symbol) + end + end else -- lazy type evaluation symbol:add_possible_type(valtype) @@ -1093,10 +1113,6 @@ function visitors.VarDecl(context, node) "variable '%s' of type '%s' is not coercible with expression of type '%s'", symbol.name, vartype, valtype) end - if valtype:is_type() then - assert(valnode and valnode.attr.holdedtype) - symbol.attr.holdedtype = valnode.attr.holdedtype - end else -- delay type evaluation symbol:add_possible_type(nil) diff --git a/spec/05-cgenerator_spec.lua b/spec/05-cgenerator_spec.lua index 5569d899..358a0eac 100644 --- a/spec/05-cgenerator_spec.lua +++ b/spec/05-cgenerator_spec.lua @@ -868,6 +868,18 @@ it("pragmas", function() ]]) end) +it("type codenames", function() + assert.generate_c([[ + local myrecord !codename 'myrecord' = @record{x: integer} + function myrecord:foo() return self.x end + local r = myrecord{} + return r:foo() + ]], { + "typedef struct myrecord {\n int64_t x;\n} myrecord;", + "static int64_t myrecord_foo(myrecord_pointer self);" + }) +end) + it("entrypoint", function() assert.run_c([[ print 'hello'