[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: Syntax trees, macros, and reflexive Lua evolution
- From: Quinn Tyler Jackson <quinn-j@...>
- Date: Tue, 09 Nov 2004 21:59:26 -0800
> > -- in user script
> > #macro_define \
> > squares (x) \
> > local t = "{"
> > for i = 1,x do t=t.."{"..i..","..i*i.."}," end \
> > return t.."}" \
> > end
>
> Eeek. :-( Crafting the textual representation lies somewhere between
> hair-raising and appallingly dreadful. :-) More importantly though,
> it's not very powerful in an engineering sense, because the parts being
> manipulated are dead text instead of active objects with introspection.
>
> Before even considering that approach, I'd think seriously about defining
> an unofficial syntax tree and creating a front-end to the current parser
> to accept the tree form as input. Then macro processing becomes a very
> clear 2nd stage in a 3-stage but still single-pass process of parsing Lua
> text into a tree, applying macros, and finally compiling the output tree.
>
> Rich Artym.
Just on a lark, after reading some of the recent posts on extending Lua with
this and that and another bit of sugar, I added a CLua interface into my
Lua-hosted $-grammars, so that lua programs could be compiled and translated
from within grammar reductions in their own lua_State.
The idea was that I could implement some kind of #macro functionality in a
"super-Lua", parse that super-Lua in the $-grammar, then, in the final
stage, using the _visit event, traverse the tree, expand the macros, and
then feed that expanded version into the CLua object for interpretation.
After some initial proof-of-concept bit-twiddling, it appears that it just
may work.
OK, to translate that into English:
Suppose we want variables in functions to default to local, and only be
"global" if a global keyword occurs before the variable:
function foo()
global a = 1; -- global
b = 2; -- local
end
We write a grammar that accepts that above, and in the tree traversal after
the first parse, "real" Lua is generated:
function foo()
a = 1;
local b = 2;
end
This could also be used for simple type checking:
function foo() returns string
return "10";
end
function foobar() returns number
return foo(); // illegal, since foo returns string
end
This would be caught in the first pass, never reaching the second pass.
This, however, would be legal:
function foo() returns string
return "10";
end
function foobar() returns number
return cast<number>(foo()); -- OK, because presumably, cast<N>(expr) casts
the expression to type N
end
I don't know if this is worthwhile -- but I'll keep experimenting and see
what I come up with.
--
Quinn Tyler Jackson
http://members.shaw.ca/grammarforge/