.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -39,3 +39,4 @@ tyche
|
|||||||
tyche-test
|
tyche-test
|
||||||
libtyche.a
|
libtyche.a
|
||||||
libtyche.so*
|
libtyche.so*
|
||||||
|
lib/compiler/compiler.lua.h
|
||||||
15
Makefile
15
Makefile
@@ -48,7 +48,6 @@ RELEASE_LDFLAGS=-flto=auto
|
|||||||
CFLAGS+=-std=c99 -D_GNU_SOURCE -fPIC -fvisibility=hidden -isystem lib/contrib -MMD -MP
|
CFLAGS+=-std=c99 -D_GNU_SOURCE -fPIC -fvisibility=hidden -isystem lib/contrib -MMD -MP
|
||||||
LDFLAGS+=
|
LDFLAGS+=
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# generic targets
|
# generic targets
|
||||||
#
|
#
|
||||||
@@ -59,7 +58,7 @@ check: tyche-test
|
|||||||
./tyche-test
|
./tyche-test
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f tyche libtyche.a libtyche.so* tyche-test **/*.o **/*.d
|
rm -f tyche libtyche.a libtyche.so* tyche-test **/*.o **/*.d compiler/compiler.h
|
||||||
|
|
||||||
install: tyche libtyche.a libtyche.so.${VERSION} lib/tyche.h
|
install: tyche libtyche.a libtyche.so.${VERSION} lib/tyche.h
|
||||||
install -m 644 libtyche.a libtyche.so.${VERSION} ${PREFIX}/lib
|
install -m 644 libtyche.a libtyche.so.${VERSION} ${PREFIX}/lib
|
||||||
@@ -73,11 +72,21 @@ uninstall:
|
|||||||
|
|
||||||
.PHONY: all check clean install uninstall
|
.PHONY: all check clean install uninstall
|
||||||
|
|
||||||
|
#
|
||||||
|
# TODO - temporary, using Lua for compilation for now
|
||||||
|
#
|
||||||
|
LDFLAGS+=-llua -lm
|
||||||
|
lib/compiler/compiler.lua.h:
|
||||||
|
luac -o lib/compiler/compiler.out lib/compiler/compiler.lua
|
||||||
|
xxd -i lib/compiler/compiler.out > lib/compiler/compiler.lua.h
|
||||||
|
rm lib/compiler/compiler.out
|
||||||
|
lib/compiler.o: lib/compiler.c lib/compiler/compiler.lua.h
|
||||||
|
|
||||||
#
|
#
|
||||||
# executable files
|
# executable files
|
||||||
#
|
#
|
||||||
|
|
||||||
LIB_SRC=lib/value.o lib/stack.o lib/array.o lib/table.o lib/heap.o lib/vm.o lib/utils.o
|
LIB_SRC=lib/value.o lib/stack.o lib/array.o lib/table.o lib/heap.o lib/vm.o lib/compiler.o lib/code.o lib/utils.o
|
||||||
|
|
||||||
tyche: CFLAGS += ${RELEASE_CFLAGS}
|
tyche: CFLAGS += ${RELEASE_CFLAGS}
|
||||||
tyche: LDFLAGS += ${RELEASE_LDFLAGS}
|
tyche: LDFLAGS += ${RELEASE_LDFLAGS}
|
||||||
|
|||||||
9
lib/code.c
Normal file
9
lib/code.c
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include "priv.h"
|
||||||
|
|
||||||
|
Code* code_load_bytecode(uint8_t* bytecode, size_t bytecode_sz)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Code* code_load_bytecode_cb(void(*read_bytes)(size_t, void*), void* data)
|
||||||
|
{
|
||||||
|
}
|
||||||
36
lib/compiler.c
Normal file
36
lib/compiler.c
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include "priv.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "lua.h"
|
||||||
|
#include "lauxlib.h"
|
||||||
|
|
||||||
|
#include "compiler/compiler.lua.h"
|
||||||
|
|
||||||
|
TYC_RESULT code_assemble(const char* code, uint8_t** bytecode, size_t* bytecode_sz)
|
||||||
|
{
|
||||||
|
lua_State* L = luaL_newstate();
|
||||||
|
|
||||||
|
int r = luaL_loadbufferx(L, (const char *) lib_compiler_compiler_out, lib_compiler_compiler_out_len, "compiler", "b");
|
||||||
|
if (r == LUA_ERRSYNTAX)
|
||||||
|
abort();
|
||||||
|
else if (r == LUA_ERRMEM)
|
||||||
|
out_of_memory();
|
||||||
|
|
||||||
|
lua_pushstring(L, code);
|
||||||
|
r = lua_pcall(L, 1, 1, 0);
|
||||||
|
if (r == LUA_ERRMEM) {
|
||||||
|
out_of_memory();
|
||||||
|
} else if (r == LUA_ERRERR) {
|
||||||
|
abort();
|
||||||
|
} else if (r == LUA_ERRRUN) {
|
||||||
|
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
||||||
|
return T_ERR_ASSEMBLER_SYNTAX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
lua_close(L);
|
||||||
|
return T_OK;
|
||||||
|
}
|
||||||
85
lib/compiler/compiler.lua
Normal file
85
lib/compiler/compiler.lua
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
----------------------
|
||||||
|
-- --
|
||||||
|
-- PARSER --
|
||||||
|
-- --
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
local function assemble(source)
|
||||||
|
local proto = {
|
||||||
|
constants = {},
|
||||||
|
functions = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
local section = ''
|
||||||
|
local current_f_id = 0
|
||||||
|
|
||||||
|
local next_label = nil
|
||||||
|
for line in source:gmatch("([^\n]+)") do
|
||||||
|
local line = line:gsub("%s*;.*$", "") -- remove comments
|
||||||
|
line = line:match("^%s*(.-)%s*$") -- trim
|
||||||
|
|
||||||
|
if #line == 0 then goto continue end
|
||||||
|
|
||||||
|
if line == ".const" then
|
||||||
|
section = 'const'
|
||||||
|
elseif line:match("%.func%s+%d+") then
|
||||||
|
section = 'function'
|
||||||
|
local f_id = tonumber(line:match("%.func%s+(%d+)"))
|
||||||
|
proto.functions[f_id] = {}
|
||||||
|
current_f_id = f_id
|
||||||
|
elseif section == 'const' then
|
||||||
|
local k, v = line:match("^%s*(%d+)%s*:%s*(.+)$")
|
||||||
|
if not k then error("Invalid row for constant: " .. line) end
|
||||||
|
if v:sub(1, 1) == '"' then
|
||||||
|
proto.constants[tonumber(k)] = line:match('"(.*)"')
|
||||||
|
else
|
||||||
|
proto.constants[tonumber(k)] = tonumber(v)
|
||||||
|
end
|
||||||
|
elseif section == 'function' then
|
||||||
|
local regexes = {
|
||||||
|
"^%s*(%a+)%s+(%d+)%s*$", -- instruction + parameter
|
||||||
|
"^%s*(%a+)%s+(@[%a_][%a%d_]*)%s*$", -- instruction + label
|
||||||
|
"^%s*(%a+)%s*$", -- instruction only
|
||||||
|
"^(@[%a_][%a%d_]*):%s*$", -- label
|
||||||
|
}
|
||||||
|
local match = false
|
||||||
|
for i,regex in ipairs(regexes) do
|
||||||
|
local inst, par = line:match(regex)
|
||||||
|
if inst then
|
||||||
|
match = true
|
||||||
|
if i == 1 then -- instruction + parameter
|
||||||
|
table.insert(proto.functions[current_f_id], { inst, tonumber(par), labels = next_label })
|
||||||
|
elseif i == 2 then -- instruction + label
|
||||||
|
table.insert(proto.functions[current_f_id], { inst, par, labels = next_label })
|
||||||
|
elseif i == 3 then -- instruction only
|
||||||
|
table.insert(proto.functions[current_f_id], { inst, labels = next_label })
|
||||||
|
elseif i == 4 then -- label
|
||||||
|
if not next_label then
|
||||||
|
next_label = { inst }
|
||||||
|
else
|
||||||
|
table.insert(next_label, inst)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if i ~= 4 then
|
||||||
|
next_label = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not match then error("Invalid instruction: " .. line) end
|
||||||
|
end
|
||||||
|
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
|
||||||
|
return proto
|
||||||
|
end
|
||||||
|
|
||||||
|
----------------------
|
||||||
|
-- --
|
||||||
|
-- GENERIC --
|
||||||
|
-- --
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
return function(source)
|
||||||
|
return { 0, 1, 2, 3, 4 }
|
||||||
|
end
|
||||||
@@ -10,6 +10,7 @@ typedef enum {
|
|||||||
T_ERR_STACK_UNDERFLOW = -1, T_ERR_STACK_FP_UNDERFLOW = -2, T_ERR_STACK_ACCESS_OUT_OF_RANGE = -3,
|
T_ERR_STACK_UNDERFLOW = -1, T_ERR_STACK_FP_UNDERFLOW = -2, T_ERR_STACK_ACCESS_OUT_OF_RANGE = -3,
|
||||||
T_ERR_HEAP_KEY_NOT_FOUND = -10,
|
T_ERR_HEAP_KEY_NOT_FOUND = -10,
|
||||||
T_ERR_TABLE_KEY_NOT_FOUND = -20,
|
T_ERR_TABLE_KEY_NOT_FOUND = -20,
|
||||||
|
T_ERR_ASSEMBLER_SYNTAX_ERROR = -30,
|
||||||
} TYC_RESULT;
|
} TYC_RESULT;
|
||||||
|
|
||||||
#endif //TYCHE_TYCHE_H
|
#endif //TYCHE_TYCHE_H
|
||||||
|
|||||||
Reference in New Issue
Block a user