+++ /dev/null
-This is metalua-0.3.9, an alpha version of the Metalua compiler.
-
-This software and its documentation are released as open source
-material, under the MIT Public License, as described in the file
-LICENSE. It uses source code and documentation from other open source
-projects, all released under the MIT License, namely:
-
-- Lua, for its virtual machine, developped by the Lua team at the
- Pontifical Catholic University of Rio de Janeiro in Brazil,
-
-- Yueliang, a Lua compiler in written in Lua, developped by Kein-Hong
- Man, constitutes the base of metalua's bytecode dumper.
-
-- Rings, a part of the Kelper project, lets handle multiple Lua states
- from within Lua.
-
-- Pluto, developped by Ben Sunshine-Hill, allow serialization and
- deserialization of arbitrary Lua data. It is used to improve
- communication across the states created with Lua Rings.
-
-- Bitlib, developped by Thomas Reuben, implement bitwise operators in
- Lua, and eases the bytecode dumping.
-
-Main changes since metalua-0.3:
-===============================
-
-- the compiler/interpreter executable has been completely
- rewritten. It address several shortcomings, such as:
-
- * integrated REPL loop;
- * ability to properly run programs, among other by passing parameters
- to them;
- * isolation of compilation processes: when several files are
- compiled, the alterations caused by one to the copmiler won't
- affect the compilation of the next ones;
- * richer API, through a standard commond line options handling library.
- * automatic insertion of a require() statement making sure that the
- metalua runtime is loaded before a program starts running, even if
- it's precompiled and run later.
-
-- the ability to process Metalua source files is optional (added with
- a "require 'metalua.compiler'" statement), and works correctly for
- all functions that might cause compilation: require(), loadstring(),
- loadfile(), dofile().
-
-- the mlc converter (the hub that handles translation between all
- program representation formats such as files, source strings, token
- streams, AST, executable functions etc.) has been completely
- rewritten.
-
-- parts of the compiler are now written in Metalua, as opposed to
- plain Lua. The compiler building process now includes a
- bootstrapping stage, i.e. the generation of a minimalist Metalua
- compiler in charge of building the final one.
-
-- isolation of compilation processes is achieved by Springs, a library
- that fusions together Lua Rings and Pluto, allowing to create
- independant Lua universe that communicate easily together.
-
-- the structural pattern matching library has been significantly improved:
- * bug fixes;
- * optimized support of multiple simultaneous values match;
- * a match statement causes an error if no pattern succeeds to capture
- the value(s)
-
--
\ No newline at end of file
+++ /dev/null
-----------------------------------------------------------------------
--- Metalua: $Id$
---
--- Summary: Main source file for Metalua compiler.
---
-----------------------------------------------------------------------
---
--- Copyright (c) 2006, Fabien Fleutot <metalua@gmail.com>.
---
--- This software is released under the MIT Licence, see licence.txt
--- for details.
---
-----------------------------------------------------------------------
-
-do
- local level = 0
- local function trace(e)
- local name = debug.getinfo(2).name or "?"
- if e=="call" then
- print((": "):rep(level) .. e .. " " .. name)
- level=level+1
- elseif e=="return" then
- level=level-1
- --print(("."):rep(level) .. e .. " " .. name)
- else
- --print(("."):rep(level) .. e .. " " .. name)
- end
- end
- --debug.sethook(trace, "cr")
-end
-
-mlc.SHOW_METABUGS = false
-PRINT_AST = false
-EXECUTE = false
-VERBOSE = false
-PRINT_LINE_MAX = 80
-UNIX_SHARPBANG = [[#!/usr/bin/env lua]]..'\n'
-LONG_NAMES = {
- help = "-h" ;
- ast = "-a" ;
- output = "-o" ;
- metabugs = "-b" ;
- execute = "-x" ;
- sharpbang = "-s" ;
- verbose = "-v" }
-
-USAGE = [[
-Metalua compiler.
-Usage: mlc [options] [files]
-Options:
- --help, -h: display this help
- --ast, -a: print the AST resulting from file compilation
- --output, -o: set the name of the next compiled file
- --execute, -x: run the function instead of saving it
- --metabugs, -b: undocumented
- --verbose, -v: verbose
-
-Options -a, -x, -b can be reversed with +a, +x, +b.
-
-Options are taken into account only for the files that appear after them,
-e.g. mlc foo.lua -x bar.lua will compile both files, but only execute bar.luac.]]
-
-local function print_if_verbose(msg)
- if VERBOSE then printf(" [%3is]: %s", os.clock(), msg) end
-end
-
--- Compilation of a file:
--- [src_name] is the name of the input file;
--- [dst_name] is the optional name of the output file; if nil, an appropriate
--- name is built from [src_name]
--- What to do with the file is decided by the global variables.
-
-local function compile_file (src_name, dst_name)
- printf("Compiling %s...", src_name)
-
- print_if_verbose "Build AST"
- local ast = mlc.ast_of_luafile (src_name)
- if not ast then error "Can't open or parse file" end
- if PRINT_AST then table.print(ast, PRINT_LINE_MAX, "nohash") end
-
- -- Execute and save:
- if EXECUTE and dst_name then
- EXECUTE = false
- dst_name = src_name .. (src_name:match ".*%.lua" and "c" or ".luac")
- print_if_verbose "Build binary dump"
- local bin = mlc.bin_of_ast (ast, src_name)
- if not ast then error "Invalid parse tree" end
- print_if_verbose "Write dump in file"
- mlc.luacfile_of_bin (bin, dst_name)
- printf("...Wrote %s; execute it:", dst_name)
- print_if_verbose "Build function from dump"
- local f = mlc.function_of_bin (bin)
- f()
-
- -- Execute, don't save
- elseif EXECUTE then
- EXECUTE = false
- print_if_verbose "Build function"
- local f = mlc.function_of_ast(ast)
- if not f then error "Invalid parse tree" end
- printf("...Execute it:", dst_name)
- f()
- -- Save, don't execute
- else
- dst_name = dst_name or
- src_name .. (src_name:match ".*%.lua" and "c" or ".luac")
- print_if_verbose "Build dump and write to file"
- mlc.luacfile_of_ast(ast, dst_name)
- printf("...Wrote %s.", dst_name)
- end
-end
-
--- argument parsing loop
-local i = 1
-while i <= #arg do
- local dst_name
- local a = arg[i]
- i=i+1
- local x = a:sub(1,1)
- if x == "-" or x == "+" then
- local bool = (x=="-")
- if bool and a[1]=="-" then
- -- double-dash: read long option
- a = LONG_NAMES [a:sub(2)]
- if not a then
- printf("Unknown option %s\n\n%s", arg[i], USAGE)
- return -1
- end
- end
- for j = 2, #a do
- local opt = a:sub (j, j)
- if opt == "h" then print (USAGE); return 0
- elseif opt == "a" then PRINT_AST = bool
- elseif opt == "o" then dst_name = arg[i]; i=i+1
- elseif opt == "b" then mlc.SHOW_METABUGS = bool
- elseif opt == "x" then EXECUTE = bool
- elseif opt == "v" then VERBOSE = bool
- elseif opt == "s" then
- if bool then UNIX_SHARPBANG = arg[i]; i=i+1
- else UNIX_SHARPBANG = nil end
- else error ("Unknown option -"..opt) end
- end
- else compile_file (a, dst_name) end
-end
-
-
--\r
-- TODO:\r
--\r
+-- * Hygiene! this stuff is absolutely not hygienic, and lexically nested\r
+-- try...with \r
+--\r
-- * give a more lua-like syntax:\r
-- > try ... (catch expr then block)* (finally block)? end\r
--\r
local try_code, catch_cases, finally_code = unpack(x)\r
local insert_return_catcher = false\r
\r
+ -- Can't be hygienize automatically by the current version of H, as\r
+ -- it must bridge from inside user code (hacjed return statements)\r
+ -- to outside macro code.\r
+ local caught_return = !mlp.gensym 'caught_return'\r
+\r
local H = H:new{side='inside'}\r
!try_code; !(catch_code or { }); !(finally_code or { })\r
\r
match x with \r
| `Return{...} -> \r
insert_return_catcher = true\r
--- FIXME: caught_return won't be tranformed because it's inside \r
--- a user-bounded block\r
- local setvar = +{stat:caught_return = -{`Table{ unpack(x) }}}\r
+ -- Setvar's 'caught_return' code can't be hygienize by H currently.\r
+ local setvar = `Set{ {caught_return}, { `Table{ unpack(x) } } }\r
x <- { setvar; `Return }; x.tag = nil;\r
$log('transformed return stat:', x, 60)\r
return 'break'\r
----------------------------------------------------------------\r
local caught_return_init, caught_return_rethrow do\r
if insert_return_catcher then\r
- caught_return_init = +{stat: local caught_return }\r
+ caught_return_init = `Local{{caught_return}}\r
caught_return_rethrow =\r
- +{stat: if caught_return then return unpack(caught_return) end}\r
+ +{stat: if -{caught_return} then return unpack(-{caught_return}) end}\r
else\r
caught_return_init, caught_return_rethrow = { }, { }\r
end\r
local original_close = io.close
---[[
function x()
- --with f = io.open 'withdo_test.mlua' do
with f1, f2 = io.open 'withdo_test.mlua', io.open 'trycatch_test.mlua' do
local t1 = f1:read '*a'
local t2 = f2:read '*a'
return #t1, #t2
end
end
---]]
-
-function x()
- --with f = io.open 'withdo_test.mlua' do
- with f1 = io.open 'withdo_test.mlua' do
- local t1 = f1:read '*a'
- return #t1
- end
-end
print(x())
\ No newline at end of file