Skip to content

Commit

Permalink
Reimplement arraytable in pure Nelua code
Browse files Browse the repository at this point in the history
  • Loading branch information
edubart committed Feb 13, 2020
1 parent 5504266 commit 9db6575
Show file tree
Hide file tree
Showing 24 changed files with 29 additions and 828 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ GID=$(shell id -g $(USER))
PWD=$(shell pwd)
DRFLAGS=--rm -it -v "$(PWD):/nelua" nelua
DFLAGS=-u $(UID):$(GID) $(DRFLAGS)
LUAMONFLAGS=-w nelua,spec,tools,examples,runtime,lib,tests -e lua,nelua,h,c -q -x
LUAMONFLAGS=-w nelua,spec,tools,examples,lib,tests -e lua,nelua -q -x
EXAMPLES=$(wildcard examples/*.nelua)
BENCHMARKS=$(wildcard benchmarks/*.nelua)
LUA=lua
Expand Down
2 changes: 2 additions & 0 deletions benchmarks/heapsort.nelua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'arraytable'

local function heapsort(a: arraytable(number))
local n = #a
local j, i, t
Expand Down
2 changes: 2 additions & 0 deletions benchmarks/sieve.nelua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'arraytable'

local function sieve(N: integer)
local is_prime: arraytable(boolean)
is_prime[1] = false
Expand Down
2 changes: 2 additions & 0 deletions examples/matmul.nelua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'arraytable'

local Matrix = @arraytable(arraytable(number))

local function matrix_transpose(a: Matrix, n: integer): Matrix
Expand Down
18 changes: 7 additions & 11 deletions lib/myarraytable.nelua → lib/arraytable.nelua
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
--TODO: lazy functions to make it generic

## strict = true
## unitname = 'nelua'

## local myarraytable = hygienize(memoize(function(T, allocator)
## local make_arraytable = hygienize(memoize(function(T, allocator)
## staticassert(traits.is_type(T), "invalid type '%s'", T)
## if allocator then
local allocator: type = #[allocator]#
Expand All @@ -26,12 +24,6 @@
end
]]

local convertible_concept: type = #[concept(function(x)
if x.type:is_array_of(T) then
return true
end
end)]#

function ArrayTableT:init() <inline>
if unlikely(not self.impl) then
self.impl = (@ArrayTableImplT*)(allocator.alloc0(#ArrayTableImplT))
Expand Down Expand Up @@ -126,7 +118,11 @@
return (@isize)(self.impl.size)
end

function ArrayTableT.__convert(values: convertible_concept): ArrayTableT <inline>
function ArrayTableT.__convert(values: #[concept(function(x)
if x.type:is_array_of(T) then
return true
end
end)]#): ArrayTableT <inline>
local self: ArrayTableT
local len: usize = (@usize)(#values)
self:reserve(len)
Expand All @@ -141,4 +137,4 @@
## return ArrayTableT
## end))

global myarraytable = #[generic(myarraytable)]#
global arraytable = #[generic(make_arraytable)]#
36 changes: 2 additions & 34 deletions nelua/analyzer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -82,27 +82,6 @@ function visitors.Nil(_, node)
attr.literal = true
end

local function visitor_ArrayTable_literal(context, node, littype)
local attr = node.attr
local childnodes = node[1]
local subtype = littype.subtype
for i, childnode in ipairs(childnodes) do
if childnode.tag == 'Pair' then
childnode:raisef("fields are disallowed for array table literal")
end
childnode.desiredtype = subtype
context:traverse_node(childnode)
local childtype = childnode.attr.type
if childtype then
local ok, err = subtype:is_convertible_from(childnode.attr)
if not ok then
childnode:raisef("in array table literal at index %d: %s", i, err)
end
end
end
attr.type = littype
end

local function visitor_Array_literal(context, node, littype)
local attr = node.attr
local childnodes = node[1]
Expand Down Expand Up @@ -202,8 +181,6 @@ function visitors.Table(context, node)
end
if not desiredtype or (desiredtype:is_table() or desiredtype.lazyable) then
visitor_Table_literal(context, node)
elseif desiredtype:is_arraytable() then
visitor_ArrayTable_literal(context, node, desiredtype)
elseif desiredtype:is_array() then
visitor_Array_literal(context, node, desiredtype)
elseif desiredtype:is_record() then
Expand Down Expand Up @@ -520,15 +497,6 @@ function visitors.EnumType(context, node)
attr.value = types.EnumType(node, subtype, fields)
end

function visitors.ArrayTableType(context, node)
local attr = node.attr
if attr.type then return end
local subtypenode = node[1]
context:traverse_node(subtypenode)
attr.type = primtypes.type
attr.value = types.ArrayTableType(node, subtypenode.attr.value)
end

function visitors.SpanType(context, node)
local attr = node.attr
if attr.type then return end
Expand Down Expand Up @@ -626,7 +594,7 @@ function visitors.GenericType(context, node)
node:raisef(err)
end
attr.type = primtypes.type
attr.value = symbol.value:eval_type(params)
attr.value = type
end

local function iargnodes(argnodes)
Expand Down Expand Up @@ -1127,7 +1095,7 @@ function visitors.ArrayIndex(context, node)
objtype = objtype.subtype
end

if objtype:is_arraytable() or objtype:is_array() or objtype:is_span() then
if objtype:is_array() or objtype:is_span() then
local indextype = indexnode.attr.type
if indextype then
if indextype:is_integral() then
Expand Down
3 changes: 0 additions & 3 deletions nelua/astdefs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,6 @@ astbuilder:register('EnumType', {
ntypes.Type:is_optional(), -- primitive type
stypes.array_of(ntypes.EnumFieldType), -- field types
})
astbuilder:register('ArrayTableType', {
ntypes.Node, -- subtype typexpr
})
astbuilder:register('ArrayType', {
ntypes.Node, -- subtype typeexpr
ntypes.Node, -- size expr
Expand Down
4 changes: 1 addition & 3 deletions nelua/cbuiltins.lua
Original file line number Diff line number Diff line change
Expand Up @@ -487,9 +487,7 @@ cbuiltins.operators = operators

function operators.len(node, emitter, argnode)
local type = argnode.attr.type
if type:is_arraytable() then
emitter:add(type, '_length(&', argnode, ')')
elseif type:is_span() then
if type:is_span() then
emitter:add('(intptr_t)(', argnode, '.size)')
else --luacov:disable
node:errorf('not implemented')
Expand Down
28 changes: 0 additions & 28 deletions nelua/ccontext.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ local Context = require 'nelua.analyzercontext'
local class = require 'nelua.utils.class'
local cdefs = require 'nelua.cdefs'
local traits = require 'nelua.utils.traits'
local pegger = require 'nelua.utils.pegger'
local fs = require 'nelua.utils.fs'
local cbuiltins = require 'nelua.cbuiltins'

local CContext = class(Context)
Expand Down Expand Up @@ -100,32 +98,6 @@ function CContext:funcretctype(functype)
end
end

function CContext:use_gc()
self:ensure_runtime('nelua_gc')
self.has_gc = true
end

local function late_template_render(context, filename, params)
params = params or {}
params.context = context
local file = fs.join(context.runtime_path, filename)
return function()
local content = fs.tryreadfile(file)
return pegger.render_template(content, params)
end
end

function CContext:ensure_runtime(name, template, params)
if self.definitions[name] then return end
if not template then
template = name
end
local deccode = late_template_render(self, template .. '.h', params)
local defcode = late_template_render(self, template .. '.c', params)
self:add_declaration(deccode, name)
self:add_definition(defcode, name)
end

function CContext:add_declaration(code, name)
if name then
assert(not self.declarations[name])
Expand Down
32 changes: 3 additions & 29 deletions nelua/cgenerator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,6 @@ typevisitors[types.Type] = function(context, type)
context:ensure_runtime_builtin('nelua_any')
elseif type:is_nil() then
context:ensure_runtime_builtin('nelua_nilable')
elseif type:is_arraytable() then
local subctype = context:ctype(type.subtype)
context:ensure_runtime(type.codename, 'nelua_arrtab', {
tyname = type.codename,
ctype = subctype,
type = type
})
context:use_gc()
else
errorer.assertf(cdefs.primitive_ctypes[type.codename],
'C type visitor for "%s" is not defined', type)
Expand Down Expand Up @@ -262,7 +254,7 @@ function visitors.Table(context, node, emitter)
local attr = node.attr
local childnodes, type = node[1], attr.type
local len = #childnodes
if len == 0 and (type:is_record() or type:is_array() or type:is_arraytable()) then
if len == 0 and (type:is_record() or type:is_array()) then
if not context.state.ininitializer then
emitter:add_ctypecast(type)
end
Expand Down Expand Up @@ -309,8 +301,6 @@ function visitors.Table(context, node, emitter)
emitter:add_ctypecast(type)
emitter:add('{{', childnodes, '}}')
end
elseif type:is_arraytable() then
emitter:add(context:typename(type), '_create((', type.subtype, '[', len, ']){', childnodes, '},', len, ')')
else --luacov:disable
error('not implemented yet')
end --luacov:enable
Expand Down Expand Up @@ -377,7 +367,6 @@ function visitors.Paren(_, node, emitter)
end

visitors.FuncType = visitors.Type
visitors.ArrayTableType = visitors.Type
visitors.ArrayType = visitors.Type
visitors.PointerType = visitors.Type

Expand Down Expand Up @@ -619,11 +608,6 @@ function visitors.ArrayIndex(context, node, emitter)
index = '__range.low'
end

if objtype:is_arraytable() then
emitter:add('*', context:typename(objtype))
emitter:add(node.assign and '_at(&' or '_get(&')
end

if objtype:is_record() and not objtype:is_span() then
if node.attr.lvalue then
emitter:add('(*')
Expand All @@ -639,9 +623,7 @@ function visitors.ArrayIndex(context, node, emitter)
emitter:add(objnode)
end

if objtype:is_arraytable() then
emitter:add(', ', index, ')')
elseif objtype:is_array() or objtype:is_span() then
if objtype:is_array() or objtype:is_span() then
emitter:add('.data[', index, ']')
else --luacov:disable
error('not implemented yet')
Expand Down Expand Up @@ -1157,15 +1139,7 @@ local function emit_main(ast, context)
if not context.entrypoint then
mainemitter:add_indent_ln('int main(int argc, char **argv) {')
mainemitter:inc_indent(2)

if context.has_gc then
mainemitter:add_indent_ln('nelua_gc_start(&nelua_gc, &argc);')
mainemitter:add_indent_ln('int result = nelua_main();')
mainemitter:add_indent_ln('nelua_gc_stop(&nelua_gc);')
mainemitter:add_indent_ln('return result;')
else
mainemitter:add_indent_ln('return nelua_main();')
end
mainemitter:add_indent_ln('return nelua_main();')
mainemitter:dec_indent(2)
mainemitter:add_indent_ln('}')
end
Expand Down
3 changes: 1 addition & 2 deletions nelua/luagenerator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ function visitors.Paren(_, node, emitter)
end
function visitors.Type() end
function visitors.FuncType() end
function visitors.ArrayTableType() end
function visitors.ArrayType() end
function visitors.IdDecl(_, node, emitter)
local name = node:args()
Expand Down Expand Up @@ -269,7 +268,7 @@ function visitors.VarDecl(context, node, emitter)
for i=istart,#varnodes do
if i > 1 then emitter:add(', ') end
local varnode = varnodes[i]
if varnode.attr.type:is_table() or varnode.attr.type:is_arraytable() then
if varnode.attr.type:is_table() then
emitter:add('{}')
elseif varnode.attr.type:is_arithmetic() then
emitter:add('0')
Expand Down
2 changes: 1 addition & 1 deletion nelua/scope.lua
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function Scope:make_checkpoint()
resolved_returntypes = tabler.copy(self.resolved_returntypes),
has_unknown_return = self.has_unknown_return
}
if self.parent then
if self.parent and self.parent.kind ~= 'root' then
checkpoint.parentcheck = self.parent:make_checkpoint()
end
return checkpoint
Expand Down
5 changes: 0 additions & 5 deletions nelua/syntaxdefs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,6 @@ local function get_parser(std)
func_type /
record_type /
enum_type /
arraytable_type /
array_type /
span_type /
range_type /
Expand Down Expand Up @@ -507,10 +506,6 @@ local function get_parser(std)
enumfield <- ({} '' -> 'EnumFieldType'
name (%ASSIGN eexpr)?
) -> to_astnode
arraytable_type <- (
{} 'arraytable' -> 'ArrayTableType'
%LPAREN etypexpr eRPAREN
) -> to_astnode
span_type <- (
{} 'span' -> 'SpanType'
%LPAREN etypexpr eRPAREN
Expand Down
28 changes: 0 additions & 28 deletions nelua/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ function Type:is_table() return self.table end
function Type:is_array() return self.array end
function Type:is_enum() return self.enum end
function Type:is_void() return self.void end
function Type:is_arraytable() return self.arraytable end
function Type:is_pointer() return self.pointer end
function Type:is_span() return self.span end
function Type:is_range() return self.range end
Expand Down Expand Up @@ -917,33 +916,6 @@ function TableType:_init(name)
Type._init(self, name, cpusize)
end

--------------------------------------------------------------------------------
local ArrayTableType = typeclass()
types.ArrayTableType = ArrayTableType
ArrayTableType.arraytable = true

function ArrayTableType:_init(node, subtype)
Type._init(self, 'arraytable', cpusize*3, node)
self.subtype = subtype
self.codename = subtype.codename .. '_arrtab'
end

function ArrayTableType:is_equal(type)
return type.name == self.name and
getmetatable(type) == getmetatable(self) and
type.subtype == self.subtype
end

function ArrayTableType:__tostring()
return sstream(self.name, '(', self.subtype, ')'):tostring()
end

function ArrayTableType.has_pointer() return true end

ArrayTableType.unary_operators.len = function()
return primtypes.isize
end

--------------------------------------------------------------------------------
local ArrayType = typeclass()
types.ArrayType = ArrayType
Expand Down
Loading

0 comments on commit 9db6575

Please sign in to comment.