titan-lang / titan Goto Github PK
View Code? Open in Web Editor NEWThe Titan programming language
Home Page: http://titan-lang.org
License: MIT License
The Titan programming language
Home Page: http://titan-lang.org
License: MIT License
Today we only have tests for the compiler internals. If some change breaks the titanc
script travis won't catch the problem.
When I compile a Titan program with clang, I get those warnings:
./foo.c:144:24: warning: unused function '_integer2str' [-Wunused-function]
inline static TString* _integer2str (lua_State *L, lua_Integer i) {
^
./foo.c:150:24: warning: unused function '_float2str' [-Wunused-function]
inline static TString* _float2str (lua_State *L, lua_Number f) {
^
These are related to the compiler internals and the end user shouldn't see them.
We have a failing test case, marked pending
:
I tried to compile
function f (a:integer, b:integer): boolean
return a and b
end
and got the following stack traceback:
lua: ./titan-compiler/coder.lua:1105: attempt to concatenate a nil value (local 'cexp')
stack traceback:
./titan-compiler/coder.lua:1105: in upvalue 'codeexp'
./titan-compiler/coder.lua:657: in function <./titan-compiler/coder.lua:656>
(...tail calls...)
./titan-compiler/coder.lua:318: in function <./titan-compiler/coder.lua:314>
(...tail calls...)
./titan-compiler/coder.lua:1243: in upvalue 'codefuncdec'
./titan-compiler/coder.lua:1656: in function 'titan-compiler.coder.generate'
./titan-compiler/driver.lua:114: in function 'titan-compiler.driver.compile'
./titan-compiler/driver.lua:107: in function 'titan-compiler.driver.compile_module'
./titanc:46: in main chunk
[C]: in ?
When I tried to change the return type from boolean
to integer
, as follows
function f (a:integer, b:integer): integer
return a and b
end
then I got the following stack traceback:
lua: ./titan-compiler/util.lua:78: Internal compiler error: missing template variable CEXP
stack traceback:
[C]: in function 'error'
./titan-compiler/util.lua:78: in function <./titan-compiler/util.lua:75>
[C]: in function 'string.gsub'
./titan-compiler/util.lua:75: in function 'titan-compiler.util.render'
(...tail calls...)
./titan-compiler/coder.lua:318: in function <./titan-compiler/coder.lua:314>
(...tail calls...)
./titan-compiler/coder.lua:1243: in upvalue 'codefuncdec'
./titan-compiler/coder.lua:1656: in function 'titan-compiler.coder.generate'
./titan-compiler/driver.lua:114: in function 'titan-compiler.driver.compile'
./titan-compiler/driver.lua:107: in function 'titan-compiler.driver.compile_module'
./titanc:46: in main chunk
[C]: in ?
(Try to be compatible with Lua about how it skips \r and \n at the start)
Lpeglabel 1.5 introduced some breaking changes to its API. Titan's parser will need to be updated to take advantage of the new and improved API.
Currently, if a (non function call) expression appears in statement position, the compiler generates errors like AssignAssign
(expected =
after variable) and EndFunc
(expected end
to close function body). Would it be possible to produce a more specific error message instead?
Is this project still alive ?
If a three-digit decimal string escape is too large (greater than 255) it will crash the compiler with an uncaught exception (bad argument to string.char). For example, the following program crashes titanc when we try to compile it
function f(): string
return "\555"
end
Ideally we should detect this and raise an MalformedEscape_decimal
parsing error. This would be super easy to do if lpeglabel implemented this feature request of mine but I think it should also be possible to implement without that.
Will I be able to treat existing lua code as if it was titan code without modification?
TypeScript does this with javascript and while I'm sure this constraint makes language development frustrating at times, it has all sorts of benefits for workflow. When I write lua code, I'm always thinking of how nice it would be to have optional static type checking.
Some time ago the part of the parser that implemented method call syntax with :
and the related test cases in the test suite were commented out. We should either bring these features back or delete them completely instead of letting them linger in this limbo.
BTW, if we bring these back we should make sure to add test cases in parser_spec to check if the NameColonExpSuf and FuncArgsExpSuf errors are being correctly generated.
Right now, the generic AST traversal from checker.lua needs to tell apart regular AST nodes (which we iterate with the children
method) and plain Lua lists (which we iterate with ipairs
). I feel that this would be cleaner if we picked only one or the other. But which way would be best?
To make everything use children
we could create a "node list" type in ast.lua and change the parser to pass all our table captures into this new type.
To make everything use ipairs we could implement the __index metamethod on our regular AST nodes.
One point in favor of unifying around the children
method is that it will let the AST traversal tell apart a node list from unrelated tables. On the other hand, unifying around ipairs
and implementing __index
would give meaning to the i
that the children
method currently returns.
Right now the parser just fails with SyntaxError
in case of syntax errors. Error messages should be more informative. The parser should also recover from errors and continue parsing.
Make sure that invalid escape syntaxes result in an error instead of being ignored or passed forward unchanged.
The current version of our parser accepts statements where the left-hand-side variable is wrapped inside one or more set of parenthesis. These should be rejected as a syntax error instead.
For example:
local x = 10
(x) = 11
Test case:
function x(a, b)
assert(#a[1] == #b)
end
Crash:
lua: ./titan-compiler/checker.lua:38: attempt to index a boolean value (local 'typenode')
stack traceback:
./titan-compiler/checker.lua:38: in upvalue 'typefromnode'
./titan-compiler/checker.lua:147: in upvalue 'secondpass'
./titan-compiler/checker.lua:753: in function 'titan-compiler.checker.check'
./titan-compiler/driver.lua:62: in function 'titan-compiler.driver.defaultloader'
./titan-compiler/checker.lua:734: in function 'titan-compiler.checker.checkimport'
titanc:36: in main chunk
[C]: in ?
Right now the Titan compiler pessimistically stores in the Lua stack any GC-able reference (references to strings and arrays) that it has stored in a native variable so the Lua garbage collector is assured to find them, but we can defer this store while we are sure no GC will occur, in the hope that by the time a GC can occur some of these references have gone out of scope and do not have to be stored to the Lua stack anymore.
To implement this store sinking, we need:
To track visibility of variables and temporaries in the code generator (no need for a full blown symbol table, a simple stack of visible
sets will do
To track variables and temporaries that are dirty
, i.e., its current value (the GC reference) changed but the new value has not been stored in the Lua stack
More aggressively put temporaries out of scope with more pushd/popd
pairs in the code
Change all places in the code generator where we store the current value of a GC-ed variable or temporary in the Lua stack to mark it as dirty instead
Implement a checkpoint
function that generates stores for all variables in the intersection of the dirty
and visible
sets, and call this function on the places where GC might occur: allocating a new string or table, calling a function...
Profit!
This is different from supporting multiple returns in functions.
Test case:
-- this works
function f()
local x = 1
local y = 2
end
-- this doesn't
function g()
local x, y = 1, 2
end
Currently, running the test suite will leave some temporary .c
and .so
files behind in the root directory of the repository and the git status
output. We should avoid doing that.
I installed Titan with luarocks for Lua 5.3
But everytime I want to tun compiler, with any file or without a file, appear a error message saying that:
/usr/bin/lua5.3: /usr/local/share/lua/5.3/titan-compiler/checker.lua:3: module 'titan-compiler.location' not found:No LuaRocks module found for titan-compiler.location
no field package.preload['titan-compiler.location']
no file '/usr/local/share/lua/5.3/titan-compiler/location.lua'
no file '/usr/local/share/lua/5.3/titan-compiler/location/init.lua'
no file '/usr/local/lib/lua/5.3/titan-compiler/location.lua'
no file '/usr/local/lib/lua/5.3/titan-compiler/location/init.lua'
no file '/usr/share/lua/5.3/titan-compiler/location.lua'
no file '/usr/share/lua/5.3/titan-compiler/location/init.lua'
no file './titan-compiler/location.lua'
no file './titan-compiler/location/init.lua'
no file '/home/jictyvoo/.luarocks/share/lua/5.3/titan-compiler/location.lua'
no file '/home/jictyvoo/.luarocks/share/lua/5.3/titan-compiler/location/init.lua'
no file '/usr/local/lib/lua/5.3/titan-compiler/location.so'
no file '/usr/lib/x86_64-linux-gnu/lua/5.3/titan-compiler/location.so'
no file '/usr/lib/lua/5.3/titan-compiler/location.so'
no file '/usr/local/lib/lua/5.3/loadall.so'
no file './titan-compiler/location.so'
no file '/home/jictyvoo/.luarocks/lib/lua/5.3/titan-compiler/location.so'
no file '/usr/local/lib/lua/5.3/titan-compiler.so'
no file '/usr/lib/x86_64-linux-gnu/lua/5.3/titan-compiler.so'
no file '/usr/lib/lua/5.3/titan-compiler.so'
no file '/usr/local/lib/lua/5.3/loadall.so'
no file './titan-compiler.so'
no file '/home/jictyvoo/.luarocks/lib/lua/5.3/titan-compiler.so'
stack traceback:
[C]: in function 'require'
/usr/local/share/lua/5.3/titan-compiler/checker.lua:3: in main chunk
[C]: in function 'require'
/usr/local/lib/luarocks/rocks-5.3/titan/dev-1/bin/titanc:5: in main chunk
[C]: in ?
So, how can I make titanc work?
Currently, there is constant folding logic spread around the whole compiler. The parser does constand folding for ..
operators and the code generator does some constant folding in the parameters of numeric for loops.
Perhaps these would belong together in a separate constant folding subroutine?
When I run titanc
for this program:
function foo(x: notvalid)
end
I get:
$ ./titanc test
./test.titan:1:17: type error: type name notvalid is invalid
./test.titan:1:17: type error: type name notvalid is invalid
The name of our rockspec file is titan-v0-scm-1.rockspec
but the name that appears in the README instructions is titan-lang-scm-1.rockspec
. And to add to the confusion we also just renamed the repository to titan instead of titan-v0.
What should the new name of the rockspec file be? Should we rename the old rockspecs or only update the name in the new rockspecs we create?
Would it be possible to compare titan to lua in regards to speed; and possibly other languages?
Does not have to be a very long comparison, just something to get people started.
Ideally it should be a fair comparison, of equal complexity; perhaps simple to medium or so, to not make this too complicated.
Please feel free to close this issue at any moment in time for any reason.
The C files our compiler is currently generating are terribly indented because it is not recognizing open braces that are followed by comments. In cases such as the following, it continues at the same indentation level instead of increasing the indentation level by one.
if (path == NULL) { /* no environment variable? */
A possible workaround would be to change our style guide to require that comments appear in lines by themselves. A more technical solution would be to make the reindent_c function a bit more clever.
What do you think would be the best course of action here?
Make sure that we have some tests to see that things that should be syntax errors really are syntax errors.
Just thought you might want to know.
For me it links to https://github.com/titan-lang//UbghZ/
Not trying to troll you, but you have heard of terra, right? It's statically typed, highly performance, same syntax as lua plus types, and uses lua as its metalanguage. It compiles using the llvm framework. It's already done. http://terralang.org/
It's great fun to work on new languages, but if you could describe in your README why and how you are taking a different approach, versus terra for example, that would be useful.
Thanks. And good luck!
0xdead
1.0e17
.5
, 1.
I think it is confusing that the Titan compiler generate a .so
by default.
Suppose this use case: a user want a single titan module to be embedded to his C program. He have his own build system, so all he wants is to generate a .c
from a .titan
and his build system will manage the rest of the compilation.
We could have a separate program that have the current behavior and call titanc
(titanc
will only generate a .c
). I believe this approach will make the code more modular.
The program bellow shouldn't be valid in Titan:
function integer()
end
parser-gen added support for node
I requested here: vsbenas/parser-gen#5 (see pg.usenodes(value)
in https://github.com/vsbenas/parser-gen/blob/master/README.md)
Hopefully that will slim the generated AST. :)
bug reported in the Lua list:
http://lua-users.org/lists/lua-l/2017-11/msg00053.html
Lua error case:
-- print biggest 8 integers on Lua 5.3.4
for i = 0x7FFFFFFFFFFFFFF8,0x7FFFFFFFFFFFFFFF do
print(i)
end
This goes in an endless loop.
Reproduced in Titan:
-- bignumbers.titan
function bignumbers(nth: integer):integer
local c = 0
for i = 0x7FFFFFFFFFFFFFF8,0x7FFFFFFFFFFFFFFF do
c = c + 1
if c == nth then
return i
end
end
return 0
end
Test from Lua:
Lua 5.3.3 Copyright (C) 1994-2016 Lua.org, PUC-Rio
> big = require("bignumbers")
> big.bignumbers
function: 0x7f5cbc0cb040
> print(big.bignumbers(1))
9223372036854775800
> for i = 1, 10 do print(big.bignumbers(i)) end
9223372036854775800
9223372036854775801
9223372036854775802
9223372036854775803
9223372036854775804
9223372036854775805
9223372036854775806
9223372036854775807
-9223372036854775808
-9223372036854775807
>
The last two numbers should be 0 and not negative numbers.
Any plans for self hosting i.e. freestanding standard library and runtime that does not depend on OS-specific features? This would make it easier to develop drivers and kernel modules.
Right now the code generation for a string literal just calls luaS_new
in place. We cannot rely on the C compiler moving this allocation outside of a loop, as it has no way to know that luaS_new
is constant, so the Titan compiler is the one that has to do it.
There is some runtime code embedded to the current compiler output. We should have a single .so
/.a
for the code shared between different Titan modules.
A solution for this issue will also fix #87.
Fails in typechecking with " is not a function".
The AssignImport
and ImportImport
error labels in titan-compiler/syntax_errors.lua
are currently unused. I think we should wither find away to use them or delete them outright.
I don't understand what is the problem with AssignImport
. The comment says that toplevelvar
accepts inputs like local bola import
but shouldn't those inputs be rejected?
--this label is not thrown in rule 'import' because rule 'toplevelvar'
--matches an invalid input like "local bola import"
{ label = "AssignImport",
msg = "Expected '='." },
As for ImportImport
, my first impression is that we can get rid of this error label in because it is perfectly OK to have toplevel variable definitions that don't have the import
keyword following the =
.
--this label is not thrown in rule 'import' because rule 'toplevelvar'
--matches an input like "local bola = X", given that X is a valid expression,
--or throws a label when X is not a valid expression
~/.luarocks/bin/titanc --tree ./ examples/sdl_demo
.//examples/sdl_demo.titan:7:1: type error: failed parsing: SDL2/SDL.h:4092:32: fail
) ( double __x ) ; ex
.//examples/sdl_quit.titan:3:1: type error: failed parsing: SDL2/SDL.h:4092:32: fail
) ( double __x ) ; ex
.//examples/sdl_quit.titan:7:38: type error: trying to access a member of value of type 'nil'
.//examples/sdl_quit.titan:9:12: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:13:11: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:13:8: type error: trying to compare values of incomparable types: invalid type and integer
.//examples/sdl_demo.titan:23:20: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:31:20: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:33:12: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:37:20: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:40:12: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:41:12: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:45:20: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:46:8: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:48:12: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:49:12: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:54:12: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:55:12: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:56:12: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:57:12: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:60:8: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:61:8: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:62:8: type error: trying to access a member of value of type 'nil'
.//examples/sdl_demo.titan:63:8: type error: trying to access a member of value of type 'nil
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.