Skip to content

Commit

Permalink
Record global variables
Browse files Browse the repository at this point in the history
  • Loading branch information
edubart committed Jun 25, 2019
1 parent e55eed9 commit 1f867c0
Show file tree
Hide file tree
Showing 20 changed files with 196 additions and 114 deletions.
4 changes: 2 additions & 2 deletions docs/assets/js/highlightjs-nelua.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ hljs.registerLanguage("nelua", function(e) {
//Lua
"function and break do else elseif end for goto if in local not or repeat return then until while " +
//Extended lua
"switch case continue defer record enum" +
"var const compconst auto"
"switch case continue compconst const global" +
"defer record enum"
,
built_in:
//Metatags and globals:
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/nelua.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![Coverage Status](https://coveralls.io/repos/github/edubart/nelua-lang/badge.svg?branch=master)](https://coveralls.io/github/edubart/nelua-lang?branch=master)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?label=license)](https://opensource.org/licenses/MIT)
[![Documentation](https://img.shields.io/website/https/edubart.github.io/nelua-lang.svg?label=docs&color=blue)](https://edubart.github.io/nelua-lang/overview/)
[![Join the chat at Gitter](https://badges.gitter.im/euluna-lang/Lobby.svg)](https://gitter.im/nelua-lang/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Gitter](https://badges.gitter.im/nelua-lang/community.svg)](https://gitter.im/nelua-lang/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
![Project Status](https://img.shields.io/badge/status-alpha-red.svg)

Nelua is a minimalistic, efficient, safe, optionally typed, ahead of time compiled, meta programmable,
Expand Down Expand Up @@ -192,7 +192,7 @@ Lua Generator:
C Generator:
- [x] Generate basic C code and compile
- [x] Primitives (integer, number, boolean)
- [x] Control structures
- [x] Control flow statements
- [x] Primitives operators
- [x] Functions
- [x] Static string
Expand Down
1 change: 0 additions & 1 deletion docs/pages/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ local function f(x: const integer)
end
```


--------------------------------------------------------------------------------
## Control flow

Expand Down
50 changes: 24 additions & 26 deletions examples/math.nelua
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
--TODO: function type overload
--TODO: implement using namespaces or method syntax sugar
--TODO: become a module
--TODO: export functions
--TODO: string compare

!!cinclude '<math.h>'
!!cinclude '<stdlib.h>'

local math = @record{}

local math_pi: compconst = 3.141592653589793
local math_maxinteger: compconst = 9223372036854775807
local math_mininteger: compconst = -9223372036854775807-1
local math_huge: number !cimport 'HUGE_VAL'
global math.pi: compconst = 3.141592653589793
global math.maxinteger: compconst = 9223372036854775807
global math.mininteger: compconst = -9223372036854775807-1
global math.huge: number !cimport 'HUGE_VAL'

function math.abs(x: number): number !cimport('fabs') end
function math.ceil(x: number): number !cimport('ceil') end
Expand Down Expand Up @@ -40,7 +38,7 @@ local function csrand(x: uint32) !cimport('srand') end

function math.atan2(x: number, y: number): number !cimport('atan2') end

function math.logbase(x: number, base: number): number
local function math_logbase(x: number, base: number): number
if base == 2 then
return clog2(x)
elseif base == 10 then
Expand All @@ -50,11 +48,11 @@ function math.logbase(x: number, base: number): number
end

function math.deg(x: number)
return x * (180.0 / math_pi)
return x * (180.0 / math.pi)
end

function math.rad(x: number)
return x * (math_pi / 180.0)
return x * (math.pi / 180.0)
end

function math.modf(x: number)
Expand Down Expand Up @@ -108,28 +106,28 @@ assert_equal(math.min(1.0, -1.0), -1)
assert_equal(math.min(-1.0, 1.0), -1)
assert_equal(math.max(1.0, -1.0), 1)
assert_equal(math.max(-1.0, 1.0), 1)
assert(math.min(math_huge, -math_huge) == -math_huge)
assert(math.max(math_huge, -math_huge) == math_huge)
assert(math.min(math.huge, -math.huge) == -math.huge)
assert(math.max(math.huge, -math.huge) == math.huge)

assert_equal(math.acos(-1.0), math_pi)
assert_equal(math.acos(-1.0), math.pi)
assert_equal(math.acos(1.0), 0)
assert_equal(math.asin(0.0), 0)
assert_equal(math.asin(1.0), math_pi/2)
assert_equal(math.asin(1.0), math.pi/2)
assert_equal(math.atan(0.0), 0)
assert_equal(math.atan(1.0), math_pi/4)
assert_equal(math.atan(1.0), math.pi/4)
assert_equal(math.atan2(0.0, 1.0), 0)
assert_equal(math.atan2(0.0, -1.0), math_pi)
assert_equal(math.atan2(0.0, -1.0), math.pi)

assert_equal(math.cos(math_pi), -1)
assert_equal(math.cos(math.pi), -1)
assert_equal(math.cos(0.0), 1)
assert_equal(math.sin(math_pi/2), 1)
assert_equal(math.sin(math.pi/2), 1)
assert_equal(math.sin(0.0), 0)
assert_equal(math.tan(math_pi/4), 1)
assert_equal(math.tan(math.pi/4), 1)
assert_equal(math.tan(0.0), 0)

assert_equal(math.deg(math_pi / 2), 90)
assert_equal(math.deg(math.pi / 2), 90)
assert_equal(math.deg(0), 0)
assert_equal(math.rad(90), math_pi / 2)
assert_equal(math.rad(90), math.pi / 2)
assert_equal(math.rad(0), 0)

assert_equal(math.sqrt(4.0), 2)
Expand All @@ -138,10 +136,10 @@ assert_equal(math.exp(0), 1)
assert_equal(math.exp(1), e)
assert_equal(math.log(1), 0)
assert_equal(math.log(e), 1)
assert_equal(math.logbase(1, 2), 0)
assert_equal(math.logbase(2, 2), 1)
assert_equal(math.logbase(1, 10), 0)
assert_equal(math.logbase(10, 10), 1)
assert_equal(math_logbase(1, 2), 0)
assert_equal(math_logbase(2, 2), 1)
assert_equal(math_logbase(1, 10), 0)
assert_equal(math_logbase(10, 10), 1)

assert_equal(math.fmod(5, 2), 1)
assert_equal(math.fmod(2.3, 5.7), 2.3)
Expand All @@ -151,8 +149,8 @@ i, f = math.modf( 5.0) assert_equal(i, 5) assert_equal(f, 0.0)
i, f = math.modf( 5.3) assert_equal(i, 5) assert_equal(f, 0.3)
i, f = math.modf(-5.3) assert_equal(i,-5) assert_equal(f,-0.3)

assert(not (math_maxinteger < math_mininteger))
assert(math.ult(math_maxinteger, math_mininteger))
assert(not (math.maxinteger < math.mininteger))
assert(math.ult(math.maxinteger, math.mininteger))
assert(math.tointeger(1.0) == 1_integer)

math.randomseed(0)
Expand Down
32 changes: 16 additions & 16 deletions nelua/astdefs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ astbuilder:register('PreprocessName', {
stypes.string, -- code
})

-- indexing
astbuilder:register('DotIndex', {
stypes.string + ntypes.PreprocessName, -- name
ntypes.Node -- expr
})
astbuilder:register('ColonIndex', {
stypes.string + ntypes.PreprocessName, -- name
ntypes.Node -- expr
})
astbuilder:register('ArrayIndex', {
ntypes.Node, -- index expr
ntypes.Node -- expr
})

-- table
astbuilder:register('Table', {
stypes.array_of(ntypes.Node) -- pair or exprs
Expand All @@ -53,7 +67,7 @@ astbuilder:register('Id', {
stypes.string + ntypes.PreprocessName, -- name
})
astbuilder:register('IdDecl', {
stypes.string + ntypes.PreprocessName, -- name
stypes.string + ntypes.PreprocessName + ntypes.DotIndex, -- name
stypes.one_of{"const", "compconst"}:is_optional(), -- mutability
ntypes.Node:is_optional(), -- typexpr
stypes.array_of(ntypes.Pragma):is_optional(), -- pragmas
Expand Down Expand Up @@ -110,20 +124,6 @@ astbuilder:register('Function', {
ntypes.Node, -- block
})

-- indexing
astbuilder:register('DotIndex', {
stypes.string + ntypes.PreprocessName, -- name
ntypes.Node -- expr
})
astbuilder:register('ColonIndex', {
stypes.string + ntypes.PreprocessName, -- name
ntypes.Node -- expr
})
astbuilder:register('ArrayIndex', {
ntypes.Node, -- index expr
ntypes.Node -- expr
})

-- calls
astbuilder:register('Call', {
stypes.array_of(ntypes.Node), -- args exprs
Expand Down Expand Up @@ -182,7 +182,7 @@ astbuilder:register('Goto', {
stypes.string + ntypes.PreprocessName -- label name
})
astbuilder:register('VarDecl', {
stypes.one_of{"local"}:is_optional(), -- scope
stypes.one_of{"local","global"}:is_optional(), -- scope
stypes.one_of{"const", "compconst"}:is_optional(), -- mutability
stypes.array_of(ntypes.IdDecl), -- var names with types
stypes.array_of(ntypes.Node):is_optional(), -- expr list, initial assignments values
Expand Down
4 changes: 2 additions & 2 deletions nelua/ccontext.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ function CContext:declname(node)
if self.scope:is_main() and traits.is_astnode(node) then
local modname = self.attr.modname or node.modname
if modname ~= '' then
declname = modname .. '_' .. declname
declname = string.format('%s_%s', modname, declname)
end
end
declname = cdefs.quotename(declname)
end
if attr.shadowcount then
declname = declname .. '__' .. attr.shadowcount
declname = string.format('%s__%d', declname, attr.shadowcount)
end
end
attr.declname = declname
Expand Down
22 changes: 11 additions & 11 deletions nelua/cgenerator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ local function visit_assignments(context, emitter, varnodes, valnodes, decl)
end
local multiretvalname
for _,varnode,valnode,valtype,lastcallindex in izipargnodes(varnodes, valnodes or {}) do
local vartype = varnode.attr.type
if not vartype:is_type() and not varnode.attr.nodecl then
local varattr = varnode.attr
local vartype = varattr.type
if not vartype:is_type() and not varattr.nodecl then
local declared, defined = false, false
if decl and context.scope:is_main() then
if decl and (context.scope:is_main()) then
-- declare main variables in the top scope
local decemitter = CEmitter(context)
if not context.attr.no_static then
decemitter:add_indent('static ')
else
decemitter:add_indent()
decemitter:add_indent()
if not context.attr.no_static and not varattr.global then
decemitter:add('static ')
end
decemitter:add(varnode)
if valnode and valnode.attr.compconst then
Expand Down Expand Up @@ -120,9 +120,9 @@ local function visit_assignments(context, emitter, varnodes, valnodes, decl)
end
defemitter:add_ln(';')
end
elseif varnode.attr.cinclude then
elseif varattr.cinclude then
-- not declared, might be an imported variable from C
context:add_include(varnode.attr.cinclude)
context:add_include(varattr.cinclude)
end
end
if usetemporary then
Expand Down Expand Up @@ -250,6 +250,7 @@ function visitors.IdDecl(context, node, emitter)
if attr.volatile then emitter:add('volatile ') end
if attr.restrict then emitter:add('restrict ') end
if attr.register then emitter:add('register ') end
if attr.static then emitter:add('static ') end
if attr.cqualifier then emitter:add(attr.cqualifier, ' ') end
emitter:add(type, ' ', context:declname(node))
if attr.cattribute then emitter:add(' __attribute__((', attr.cattribute, '))') end
Expand Down Expand Up @@ -691,7 +692,6 @@ end

function visitors.VarDecl(context, node, emitter)
local varscope, mutability, varnodes, valnodes = node:args()
node:assertraisef(varscope == 'local', 'global variables not supported yet')
visit_assignments(context, emitter, varnodes, valnodes, true)
end

Expand All @@ -709,7 +709,7 @@ function visitors.FuncDef(context, node)
local type = attr.type
local numrets = type:get_return_count()
local qualifier = ''
if not attr.entrypoint and not context.attr.no_static then
if not attr.entrypoint and not context.attr.no_static and not attr.global then
qualifier = 'static '
end
local declare, define = not attr.nodecl, true
Expand Down
19 changes: 10 additions & 9 deletions nelua/symbol.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ function Symbol:_init(name, node, type)
self.attr = attr
attr.name = name
attr.codename = name
attr.type = type
if type then
attr.type = type
end
end

function Symbol:add_possible_type(type, required)
Expand All @@ -33,20 +35,19 @@ function Symbol:link_node(node)
if node.attr == self.attr then
return
end
if not self.node then
-- this is symbol without a parent node, merge attrs into others nodes and link
local attr = node.attr
for k,v in pairs(self.attr) do
if next(node.attr) == nil then
node.attr = self.attr
else
-- merge attrs into others node and link
local attr = self.attr
for k,v in pairs(node.attr) do
if attr[k] == nil then
attr[k] = v
else
assert(attr[k] == v, 'cannot link to a node with different attributes')
end
end
self.attr = attr
else
assert(next(node.attr) == nil, 'cannot link to a node with attributes')
node.attr = self.attr
node.attr = attr
end
end

Expand Down
Loading

0 comments on commit 1f867c0

Please sign in to comment.