feat(lua): use (** ... **) instead of {{ ... }} for nested Lua scripts

The token }} is a bad delimiter for blocks of Lua script code nested in Lean files.
The problem is that the sequence }} occurs very often in Lua code because Lua uses { and } to build tables/lists/arrays.
Here is an example of Lua code that contains the sequence }}
     t = {{1, 2}, {2, 3}, {3, 4}}

In Lean, (* ... *) is used to create comments. Thus, (** ... **) code blocks will not affect
valid Lean files. It also looks reasonably good.

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-11-12 16:05:46 -08:00
parent 8190d4fed5
commit 9a5f86fce6
7 changed files with 52 additions and 63 deletions

View file

@ -132,8 +132,6 @@ bool scanner::check_next_is_digit() {
} }
void scanner::read_comment() { void scanner::read_comment() {
lean_assert(curr() == '*');
next();
int nest = 1; int nest = 1;
while (true) { while (true) {
if (curr() == '*') { if (curr() == '*') {
@ -337,53 +335,43 @@ scanner::token scanner::read_string() {
} }
scanner::token scanner::read_script_block() { scanner::token scanner::read_script_block() {
lean_assert(curr() == '{');
next();
m_script_line = m_line; m_script_line = m_line;
m_script_pos = m_pos; m_script_pos = m_pos;
m_buffer.clear(); m_buffer.clear();
int num_open_blocks = 1;
while (true) { while (true) {
char c = curr(); char c1 = curr();
if (c == EOF) { if (c1 == EOF)
throw_exception("unexpected end of script"); throw_exception("unexpected end of script");
} else if (c == '{') { next();
m_buffer += '{'; if (c1 == '*') {
next();
c = curr();
if (c == '{')
num_open_blocks++;
else if (c == '\n')
new_line();
else if (c == EOF)
throw_exception("unexpected end of script");
m_buffer += c;
next();
} else if (c == '}') {
next();
char c2 = curr(); char c2 = curr();
if (c2 == '}') { if (c2 == EOF)
next();
num_open_blocks--;
if (num_open_blocks == 0)
return token::ScriptBlock;
} else if (c2 == '\n') {
new_line();
next();
} else if (c2 == EOF) {
throw_exception("unexpected end of script"); throw_exception("unexpected end of script");
} else { next();
if (c2 == '*') {
char c3 = curr();
if (c3 == EOF)
throw_exception("unexpected end of script");
next(); next();
if (c3 == ')') {
return token::ScriptBlock;
} else {
if (c3 == '\n')
new_line();
m_buffer += c1;
m_buffer += c2;
m_buffer += c3;
}
} else {
if (c2 == '\n')
new_line();
m_buffer += c1;
m_buffer += c2;
} }
m_buffer += c;
m_buffer += c2;
} else if (c == '\n') {
new_line();
m_buffer += '\n';
next();
} else { } else {
m_buffer += c; if (c1 == '\n')
next(); new_line();
m_buffer += c1;
} }
} }
} }
@ -407,18 +395,19 @@ scanner::token scanner::scan() {
case '(': case '(':
next(); next();
if (curr() == '*') { if (curr() == '*') {
read_comment(); next();
break; if (curr() == '*') {
next();
return read_script_block();
} else {
read_comment();
break;
}
} else { } else {
return token::LeftParen; return token::LeftParen;
} }
case ')': next(); return token::RightParen; case ')': next(); return token::RightParen;
case '{': case '{': next(); return token::LeftCurlyBracket;
next();
if (curr() == '{')
return read_script_block();
else
return token::LeftCurlyBracket;
case '}': next(); return token::RightCurlyBracket; case '}': next(); return token::RightCurlyBracket;
case 'a': return read_a_symbol(); case 'a': return read_a_symbol();
case 'b': return read_b_symbol(); case 'b': return read_b_symbol();

View file

@ -1,7 +1,7 @@
Variable x : Int Variable x : Int
{{ (**
print("hello world from Lua") print("hello world from Lua")
}} **)
Variable y : Int Variable y : Int

View file

@ -1,6 +1,6 @@
Variable x : Bool Variable x : Bool
{{ (**
a = {} a = {}
print("hello world") print("hello world")
print ("ok") print ("ok")
@ -9,7 +9,7 @@ Variable x : Bool
y = 20 y = 20
} }
rint ("ok") rint ("ok")
}} **)
Variable y : Bool Variable y : Bool

View file

@ -1,6 +1,6 @@
Variable x : Int Variable x : Int
{{ (**
dofile("script.lua") dofile("script.lua")
}} **)

View file

@ -1,12 +1,12 @@
Variable x : Int Variable x : Int
{{ (**
-- Add a variable to the environment using Lua -- Add a variable to the environment using Lua
-- The type of the new variable is equal to the type -- The type of the new variable is equal to the type
-- of x -- of x
typeofx = env():check_type(Const("x")) typeofx = env():check_type(Const("x"))
print("type of x is " .. tostring(typeofx)) print("type of x is " .. tostring(typeofx))
env():add_var("y", typeofx) env():add_var("y", typeofx)
}} **)
Check x + y Check x + y

View file

@ -1,13 +1,13 @@
Variable x : Int Variable x : Int
{{ (**
local N = 100 local N = 100
-- Create N variables with the same type of x -- Create N variables with the same type of x
typeofx = env():check_type(Const("x")) typeofx = env():check_type(Const("x"))
for i = 1, N do for i = 1, N do
env():add_var("y_" .. i, typeofx) env():add_var("y_" .. i, typeofx)
end end
}} **)
Show Environment 101 Show Environment 101
Check x + y_1 + y_2 Check x + y_1 + y_2

View file

@ -1,19 +1,19 @@
Variable x : Int Variable x : Int
Set pp::notation false Set pp::notation false
{{ (**
print(get_options()) print(get_options())
}} **)
Check x + 2 Check x + 2
{{ (**
o = get_options() o = get_options()
o = o:update(name('lean', 'pp', 'notation'), true) o = o:update(name('lean', 'pp', 'notation'), true)
set_options(o) set_options(o)
print(get_options()) print(get_options())
}} **)
Check x + 2 Check x + 2
{{ (**
set_option(name('lean', 'pp', 'notation'), false) set_option(name('lean', 'pp', 'notation'), false)
print(get_options()) print(get_options())
}} **)
Variable y : Int Variable y : Int
Check x + y Check x + y