Would my DSL for Lua work...? (this seems too simply to be true)
Asked Answered
O

3

5

I really love Lua as a programming language BUT, it bugs me unbelievably to have to constantly type "local" for all my local variables.

It just makes my code look more cluttered.

So I am wondering, can I create a Domain Specific Language (DSL) on top of Lua to simply have the following variable naming convention.

  1. If a variable name is in ALL CAPITAL LETTERS, then it's a global variable
  2. Else, the variable is a local variable

Question: Would this work - Yes or no?

In other words:

-- In Lua 5.2
isGlobalinLua  = "is global in default Lua"
GLOBALVAR      = "is global var in default Lua"
local localvar = "is local var in default Lua"

-- In my DSL Lua language
isLocalinDSLLua = "is local in DSL Lua"  -- translates to: local isLocalinDSLLua = ...
GLOBALVAR       = "is global DSL Lua"
localvar        = "is local var in DSL Lua"  -- translates to: local localvar = ...

So now, the following code in default Lua:

myglobal = 10
local a = 1
if a > 1 then
    local b = 2
    print b
else
    local c = 3
    print c + myglobal
end

With my DSL Lua:

MYGLOBAL = 10
a = 1
if a > 1 then
    b = 2
    print b
else
    c = 3
    print c + MYGLOBAL
end

UPDATE:

What about local functions?

How would the following code work?

myfunc = function (...)   -- local myfunc = function (...)

I'm not certain I'd want to make every global function in all caps.

Maybe I just ignore functions and require the 'local' identifier ... thoughts?

Octonary answered 16/3, 2012 at 21:26 Comment(4)
Interesting question. +1 I am interested in seeing if this is correct or what the correct way of doing this would be.Durware
Of course you "can" do this; write a preprocessor that reads your DSL and outputs Lua source. This is not a trivial task, nor is it obvious to me how worthwhile it would be. I personally see little point in DSLs that work at the same level of abstraction as the implementation language; they do not save time nor prevent errors. The "domain" in a "domain-specific" language usually refers to the end-user domain; such a game player, accountant, businessman, et al.Tackett
So, after a year, what came out of this idea?Goeger
@lhf, I didn't create this but it's given me inspiration. moonscript.orgOctonary
P
3

Moonscript already has all variables local by default and you only need to use export keyword to declare a global. It's a very nice next-generation, coffeescript-like language and it compiles to Lua. I use it wherever I used to use Lua.

foo = 'bar' -- local
square (x) -> x*x -- local

-- globals
export square
export MY_GLOBAL = 12

export class Foo
    new: (bar) => @bar = bar -- self.bar = bar
    get_bar: => @bar
Pitching answered 6/4, 2013 at 21:46 Comment(1)
Unfortunately, I'm not a coffeescript fan. Do you know how I could pull out the portion of Moonscript that I want to use without using the rest?Octonary
M
5

Since the change you want is relatively simple, you basically have two options. You can try out Metalua:

Metalua is a language and a compiler which provide ...

  • A complete macro system, similar in power to what's offfered by Lisp dialects or Template Haskell; manipulated programs can be seen as source code, as abstract syntax trees, or as an arbitrary mix thereof, whichever suits your task better.
  • A dynamically extensible parser, which lets you support your macros with a syntax that blends nicely with the rest of the language.

Or you can use token filters:

The token filter works by giving you the opportunity to inspect and alter the stream of tokens coming from the lexer before they go to the parser. You get to see only tokens and you are only allowed to generate tokens -- you're not allowed to see the text coming to the lexer nor to generate text to go into the lexer.

Both approaches have their pros and cons. Metalua allows you to do high-level language modifications in Lua, but has a steeper learning curve. Token filters allow you to do simple modifications to the token stream, but have a limited power (see the 2005 talk).

I'm not sure if token filters are enough for your case, because inserting local before every lowercase-starting identifier in assignment will only work for simple cases. What about the following code?

a = 1
a = a * a

Do you want to convert it to a single local, or you want two?

local a = 1     vs.    local a = 1
a * a                  local a = a * a  -- valid in Lua, creates a new variable
Mosque answered 16/3, 2012 at 22:2 Comment(0)
G
3

Yes, you can do this, but the result is not called a "domain-specific language". It is called a "preprocessor".

I, too, was once incredibly bugged by a problem with Lua—it lacks a switch or case statement. I actually wound up modifying the implementation to support this feature. But eventually I decided I didn't care to be programming in a dialect that only I used.

If you have C programming skills, the Lua implementation is very clean, and the easiest way for you to achieve your goal is probably just to modify the implementation.

Grattan answered 17/3, 2012 at 1:48 Comment(0)
P
3

Moonscript already has all variables local by default and you only need to use export keyword to declare a global. It's a very nice next-generation, coffeescript-like language and it compiles to Lua. I use it wherever I used to use Lua.

foo = 'bar' -- local
square (x) -> x*x -- local

-- globals
export square
export MY_GLOBAL = 12

export class Foo
    new: (bar) => @bar = bar -- self.bar = bar
    get_bar: => @bar
Pitching answered 6/4, 2013 at 21:46 Comment(1)
Unfortunately, I'm not a coffeescript fan. Do you know how I could pull out the portion of Moonscript that I want to use without using the rest?Octonary

© 2022 - 2024 — McMap. All rights reserved.