Skip to content

Commit

Permalink
Experimental memory lib prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
edubart committed Jul 11, 2019
1 parent 608ad47 commit 916123b
Show file tree
Hide file tree
Showing 20 changed files with 168 additions and 70 deletions.
4 changes: 2 additions & 2 deletions docs/pages/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This overview try to focus more on those features.

Simple hello world program, just like in Lua:

```nelua
```lua
print 'Hello world!'
```

Expand Down Expand Up @@ -236,7 +236,7 @@ repeat
until a == 0
```

Note that variables declarated inside repeat scope are visible on it's condition expression.
Note that variables declared inside repeat scope are visible on it's condition expression.

### For

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ This is a basic tutorial for the programming language Nelua.

## Your first program

```
```nelua
print 'Hello world'
```

Expand Down
97 changes: 97 additions & 0 deletions lib/memory.nelua
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
## state.strict = true
## state.modname = 'nelua'
## state.nohashcodenames = true

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

local function memcpy(dest: pointer, src: pointer, n: csize): pointer !cimport 'memcpy' end
local function memmove(dest: pointer, src: pointer, n: csize): pointer !cimport 'memmove' end
local function memset(s: pointer, c: cint, n: csize): pointer !cimport 'memset' end

local function malloc(size: csize): pointer !cimport 'malloc' end
local function calloc(nmemb: csize, size: csize): pointer !cimport 'calloc' end
local function realloc(ptr: pointer, size: csize): pointer !cimport 'realloc' end
local function free(ptr: pointer): void !cimport 'free' end

global memory = @record{}

local memslice = @record {
data: byte[0]*,
size: usize
}

function memory.alloc(size: usize): memslice
assert(size > 0)
local data = @byte[0]*(malloc(size))
assert(data)
return memslice { data, size }
end

function memory.alloc0(size: usize): memslice
assert(size > 0)
local data = @byte[0]*(calloc(1, size))
assert(data)
return memslice { data, size }
end

function memory.realloc(s: memslice*, size: usize)
assert(size > 0)
s.data = @byte[0]*(realloc(s.data, size))
assert(s.data)
s.size = size
end

function memory.realloc0(s: memslice*, size: usize)
assert(size > 0)
s.data = @byte[0]*(realloc(s.data, size))
assert(s.data)
if size > s.size then
memset(&s.data[s.size], 0, size - s.size)
end
s.size = size
end

function memory.dealloc(s: memslice*)
if s.size == 0 then
return
end
s.data = nilptr
s.size = 0
free(s.data)
end

function memory.copy(dest: memslice, src: memslice)
assert(dest.size >= src.size)
memcpy(dest.data, src.data, src.size)
end

function memory.move(dest: memslice, src: memslice)
assert(dest.size >= src.size)
memcpy(dest.data, src.data, src.size)
end

function memory.set(dest: memslice, x: byte)
memset(dest.data, x, dest.size)
end

-- tests
local function assertmem(s: memslice, x: byte)
for i=0_usize,<s.size do
assert(s.data[i] == x)
end
end

local mem = memory.alloc0(4)
assert(mem.size == 4)
assertmem(mem, 0)

memory.realloc0(mem, 8)
assert(mem.size == 8)
assertmem(mem, 0)

memory.set(mem, 0xff)
assertmem(mem, 0xff)

memory.dealloc(mem)
assert(mem.size == 0)
2 changes: 1 addition & 1 deletion nelua/astbuilder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ local ASTBuilder = class()

local function get_astnode_shapetype(nodeklass)
return shapetypes.custom(function(val)
if class.is_a(val, nodeklass) then return true end
if class.is(val, nodeklass) then return true end
return nil, string.format('expected type "ASTNode", got "%s"', type(val))
end)
end
Expand Down
2 changes: 1 addition & 1 deletion nelua/preprocessor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ function preprocessor.preprocess(context, ast)
if ppfunc then
ok, err = pcall(ppfunc)
end
if except.is_exception(err) then
if except.isexception(err) then
except.reraise(err)
else
--TODO: better error messages
Expand Down
16 changes: 8 additions & 8 deletions nelua/runner.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ local function run(argv, redirect)
local config = configer.parse(argv)
local generator = require('nelua.' .. config.generator .. 'generator')
if config.timing then
console.debugf('startup %.1f ms', timer:elapsed_restart())
console.debugf('startup %.1f ms', timer:elapsedrestart())
end

local syntax = syntaxdefs(config.standard)
if config.timing then
console.debugf('compile grammar %.1f ms', timer:elapsed_restart())
console.debugf('compile grammar %.1f ms', timer:elapsedrestart())
end


Expand All @@ -37,7 +37,7 @@ local function run(argv, redirect)
local ast = parser:parse(input, infile)

if config.timing then
console.debugf('parse AST %.1f ms', timer:elapsed_restart())
console.debugf('parse AST %.1f ms', timer:elapsedrestart())
end

-- only checking syntax?
Expand All @@ -55,7 +55,7 @@ local function run(argv, redirect)
typechecker.analyze(ast, parser)

if config.timing then
console.debugf('analyze AST %.1f ms', timer:elapsed_restart())
console.debugf('analyze AST %.1f ms', timer:elapsedrestart())
end

if config.print_analyzed_ast then
Expand All @@ -69,7 +69,7 @@ local function run(argv, redirect)
local code, compileopts = generator.generate(ast)

if config.timing then
console.debugf('generate code %.1f ms', timer:elapsed_restart())
console.debugf('generate code %.1f ms', timer:elapsedrestart())
end

-- only printing generated code?
Expand All @@ -87,7 +87,7 @@ local function run(argv, redirect)
local sourcefile = compiler.compile_code(code, outcachefile, compileopts)

if config.timing then
console.debugf('compile code %.1f ms', timer:elapsed_restart())
console.debugf('compile code %.1f ms', timer:elapsedrestart())
end

local dorun = not config.compile and not config.compile_binary
Expand All @@ -99,7 +99,7 @@ local function run(argv, redirect)
binaryfile = compiler.compile_binary(sourcefile, outcachefile, compileopts)

if config.timing then
console.debugf('compile binary %.1f ms', timer:elapsed_restart())
console.debugf('compile binary %.1f ms', timer:elapsedrestart())
end
end

Expand All @@ -112,7 +112,7 @@ local function run(argv, redirect)
if sout then io.stdout:write(sout) io.stdout:flush() end
if serr then io.stderr:write(serr) io.stderr:flush() end
if config.timing then
console.debugf('run %.1f ms', timer:elapsed_restart())
console.debugf('run %.1f ms', timer:elapsedrestart())
end
return status
end
Expand Down
4 changes: 2 additions & 2 deletions nelua/scope.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function Scope:get_symbol(name, node, required)
end
end
if not symbol and required and self.context.state.strict and not self.context.preprocessing then
node:raisef("undeclarated symbol '%s'", name)
node:raisef("undeclared symbol '%s'", name)
end
return symbol
end
Expand All @@ -84,7 +84,7 @@ function Scope:add_symbol(symbol)
local oldsymbol = self.symbols[name]
if oldsymbol and (not oldsymbol.node or oldsymbol.node ~= symbol.node) then
symbol.node:assertraisef(not self.context.state.strict,
"symbol '%s' shadows pre declarated symbol with the same name", name)
"symbol '%s' shadows pre declared symbol with the same name", name)

-- symbol redeclaration, resolve old symbol type before replacing it
symbol_resolve_type(oldsymbol)
Expand Down
6 changes: 3 additions & 3 deletions nelua/typechecker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ function visitors.VarDecl(context, node)
for _,varnode,valnode,valtype in izipargnodes(varnodes, valnodes) do
assert(varnode.tag == 'IdDecl')
if varscope == 'global' then
varnode:assertraisef(context.scope:is_static_storage(), 'global variables can only be declarated in top scope')
varnode:assertraisef(context.scope:is_static_storage(), 'global variables can only be declared in top scope')
varnode.attr.global = true
end
if context.state.nostatic then
Expand Down Expand Up @@ -1278,7 +1278,7 @@ function visitors.FuncDef(context, node)
else
context.infuncdef = node
if varscope == 'global' then
varnode:assertraisef(context.scope:is_static_storage(), 'global function can only be declarated in top scope')
varnode:assertraisef(context.scope:is_static_storage(), 'global function can only be declared in top scope')
varnode.attr.global = true
end
if decl then
Expand All @@ -1291,7 +1291,7 @@ function visitors.FuncDef(context, node)
context:traverse(retnodes)
local returntypes
if #retnodes > 0 then
-- returns types are pre declarated
-- returns types are pre declared
returntypes = tabler.imap(retnodes, function(retnode)
return retnode.attr.holdedtype
end)
Expand Down
5 changes: 3 additions & 2 deletions nelua/utils/bn.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ function bn.isintegral(v)
end

function bn.tointeger(v)
if v:isintegral() then
return tonumber(tostring(v:trunc()))
local vint = v:trunc()
if v == vint then
return tonumber(tostring(vint))
end
end

Expand Down
6 changes: 3 additions & 3 deletions nelua/utils/class.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ local metamagic = require 'nelua.utils.metamagic'
local class = {}

-- called when creating a new object
local function create_object(klass, ...)
local function createobject(klass, ...)
local object = setmetatable({}, klass)
local init = object._init
if init then init(object, ...) end
Expand All @@ -21,11 +21,11 @@ function class.new(base)
end
end
klass.__index = klass
return setmetatable(klass, { __index = base, __call = create_object })
return setmetatable(klass, { __index = base, __call = createobject })
end

-- check if a value is an instance of a class
function class.is_a(val, T)
function class.is(val, T)
local mt = getmetatable(val)
while mt do
local mtindex = rawget(mt, '__index')
Expand Down
16 changes: 8 additions & 8 deletions nelua/utils/except.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ except.Exception = Exception

local function raise(e, level)
level = (level or 1) + 1
if class.is_a(e, Exception) then
if class.is(e, Exception) then
error(e, level)
elseif traits.is_string(e) then
error(Exception({ message = e }, level), level)
Expand All @@ -65,19 +65,19 @@ function except.assertraisef(cond, message, ...)
return cond
end

function except.is_exception(e, label)
return class.is_a(e, Exception) and (not label or (label == e.label))
function except.isexception(e, label)
return class.is(e, Exception) and (not label or (label == e.label))
end

function except.reraise(e)
if class.is_a(e, Exception) then
if class.is(e, Exception) then
e.traceback = debug.traceback(e.traceback)
end
error(e, 0)
end

local function try_error_handler(e)
if class.is_a(e, Exception) then
local function tryerrhandler(e)
if class.is(e, Exception) then
return e
elseif type(e) == 'string' then
return debug.traceback(e, 2)
Expand All @@ -97,9 +97,9 @@ end
-- an exception is considered caught when the call to the handler returns true
-- the handler can be a table of labeled exceptions function handlers or a function
function except.try(f, handler)
local ok, e = xpcall(f, try_error_handler)
local ok, e = xpcall(f, tryerrhandler)
if not ok then
if class.is_a(e, Exception) then
if class.is(e, Exception) then
if handler then
if traits.is_table(handler) then handler = handler[e.label or 'Exception'] end
if handler and handler(e) then return true end
Expand Down
8 changes: 4 additions & 4 deletions nelua/utils/executor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ local executor = {}

-- luacov:disable

-- try to use luaposix exec (faster because we skil shell creation)
-- try to use luaposix exec (faster because we skip shell creation)
local hasposix, posix_pexec = pcall(function()
local unistd = require 'posix.unistd'
local wait = require 'posix.sys.wait'.wait
Expand Down Expand Up @@ -104,7 +104,7 @@ local pexec = hasposix and posix_pexec or pl_pexec

--luacov:enable

local function convert_args(exe, args)
local function convertargs(exe, args)
if not args then
args = pegger.split_execargs(exe)
exe = args[1]
Expand All @@ -115,13 +115,13 @@ end

-- luacov:disable
function executor.exec(exe, args)
exe, args = convert_args(exe, args)
exe, args = convertargs(exe, args)
return pexec(exe, args)
end
--luacov:enable

function executor.execex(exe, args)
exe, args = convert_args(exe, args)
exe, args = convertargs(exe, args)
return pexec(exe, args, true)
end

Expand Down
4 changes: 2 additions & 2 deletions nelua/utils/iterators.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ end

-- pairs() for string keys only
function iterators.spairs(t)
return function(_t, k)
return function(st, k)
local v
repeat
k, v = next(_t, k)
k, v = next(st, k)
until k == nil or type(k) == 'string'
if k ~= nil then
return k, v
Expand Down

0 comments on commit 916123b

Please sign in to comment.