Assignment in C++ like DSL

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Assignment in C++ like DSL

Abhijit Nandy
Hi,

I have a DSL to parse C++ like syntax here:

https://github.com/synth2014/DSLsBasedOnLua/blob/master/cpp/cpp.lua


It can parse syntax like:

class 'A': public 'B'
{
public: 
    int 'm',
    int 'n'(10),
    foo = function() 
        print("function foo called!") 
    end,
    
private:
    str 's' 'hi',
    int 'i' '3',
    bar = function() 
        print("function bar called!") 
    end,
}

I would love to be able to say:
int 'm' = 3

But putting the '=' breaks the syntax. Is there any way to enable this kind of syntax?

Thanks,
Abhijit
Reply | Threaded
Open this post in threaded view
|

Re: Assignment in C++ like DSL

Ross Bencina


On 24/12/2015 6:21 PM, Abhijit Nandy wrote:
> I would love to be able to say:
> int 'm' = 3
>
> But putting the '=' breaks the syntax. Is there any way to enable this
> kind of syntax?

Just an idea:

I don't think that you can overload the assignment operator, but maybe
you could overload '<='. e.g.:

int 'm' <= 3

I think you'd need to make defaultValueParser a table with a __call
metamethod. (I don't think you can set a metatable on a plain function.)

 >>>>>>>>>

defaultValueParser = {}

mt = {
   -- put your old defaultValueParser implementation in __call:
   __call = function(self, x) print(">", x, "<") end,
   __le = function(lhs, rhs) lhs(rhs); end -- invoke __call
}
setmetatable(defaultValueParser, mt)

int = function(y) return defaultValueParser end

----
-- example usage:

x = {
   int 'm',
   int 'm'(10),
   int 'm' <= 8
};

<<<<<<<<<<


http://www.lua.org/manual/5.2/manual.html#2.4
http://lua-users.org/wiki/MetamethodsTutorial

Ross.

Reply | Threaded
Open this post in threaded view
|

Re: Assignment in C++ like DSL

Abhijit Nandy
Thanks Ross, I will try that out.

Is there any reason why the assignment operator cannot be overloaded in Lua?

Abhijit

On Thu, Dec 24, 2015 at 2:31 PM, Ross Bencina <[hidden email]> wrote:


On 24/12/2015 6:21 PM, Abhijit Nandy wrote:
I would love to be able to say:
int 'm' = 3

But putting the '=' breaks the syntax. Is there any way to enable this
kind of syntax?

Just an idea:

I don't think that you can overload the assignment operator, but maybe you could overload '<='. e.g.:

int 'm' <= 3

I think you'd need to make defaultValueParser a table with a __call metamethod. (I don't think you can set a metatable on a plain function.)

>>>>>>>>>

defaultValueParser = {}

mt = {
  -- put your old defaultValueParser implementation in __call:
  __call = function(self, x) print(">", x, "<") end,
  __le = function(lhs, rhs) lhs(rhs); end -- invoke __call
}
setmetatable(defaultValueParser, mt)

int = function(y) return defaultValueParser end

----
-- example usage:

x = {
  int 'm',
  int 'm'(10),
  int 'm' <= 8
};

<<<<<<<<<<


http://www.lua.org/manual/5.2/manual.html#2.4
http://lua-users.org/wiki/MetamethodsTutorial

Ross.


Reply | Threaded
Open this post in threaded view
|

Re: Assignment in C++ like DSL

steve donovan
On Thu, Dec 24, 2015 at 7:23 PM, Abhijit Nandy <[hidden email]> wrote:
> Is there any reason why the assignment operator cannot be overloaded in Lua?

Because the __newindex metamethod [1] only fires when a _new_ table
index is created - otherwise it would be inefficient if it fired for
every assignment.

However, you _can_ do int.m = 3 !  'int' is a table with a __newindex
- it will be called with the table itself ('self') and the key ('m').
As long as you don't actually store 'm' in that table, the metamethod
will fire each time. You can make it do anything you like...

[1] http://www.lua.org/pil/13.4.2.html

Reply | Threaded
Open this post in threaded view
|

Re: Assignment in C++ like DSL

Duncan Cross
In reply to this post by Abhijit Nandy
On Thu, Dec 24, 2015 at 5:23 PM, Abhijit Nandy <[hidden email]> wrote:
> Thanks Ross, I will try that out.
>
> Is there any reason why the assignment operator cannot be overloaded in Lua?
>
> Abhijit

In Lua, assignment is actually *not* a true expression operator. It's
only a statement, which is why you can't do things like "a = b = c =
1", or "while ((a = a + 1) < 10)" like you can in other, more C-based
languages. My understanding is that keeping this strict division
between expression and statement is part of the simplicity that Lua
needs to keep its parser as fast as possible.

-Duncan

Reply | Threaded
Open this post in threaded view
|

Re: Assignment in C++ like DSL

steve donovan
On Thu, Dec 24, 2015 at 10:04 PM, Duncan Cross <[hidden email]> wrote:
> languages. My understanding is that keeping this strict division
> between expression and statement is part of the simplicity that Lua
> needs to keep its parser as fast as possible.

I suspect that relaxing this rule would not make the parser much
slower; the simplicity of Lua is intended to help the _human_ parsing
the code. E.g. the famous C/C++ mistake 'if (a = b)' is not possible.
Code is easier to read when there aren't too many possible surprises.

Reply | Threaded
Open this post in threaded view
|

Re: Assignment in C++ like DSL

Abhijit Nandy
I suspect that relaxing this rule would not make the parser much
slower; the simplicity of Lua is intended to help the _human_ parsing
the code. E.g. the famous C/C++ mistake 'if (a = b)' is not possible.
Code is easier to read when there aren't too many possible surprises.

Lets says speed was not much of an issue, then what modifications would be needed to have assignment as an operator in tables.

So if there is say, an __assign() meta-function present in a table, then that is called with the value being assigned.

Also C++ allows references on the left hand side of an assignment statement. So a function which returns a reference can have a value assigned to the returned variable.

If this were present in Lua then having an assignment to the result of a function call would be really easy. Since tables are passed by reference, a function could return the table. Then the assignment operator could be invoked on it.

local tbl = {}
tbl.value = 0

mt = { __assign(value) = function(value) tbl.value = value end}
setmetatable(tbl, mt)

function foo(tbl)
    return tbl
end

foo(tbl) = 2

-- tbl.value = 2 now


On Fri, Dec 25, 2015 at 1:24 PM, steve donovan <[hidden email]> wrote:
On Thu, Dec 24, 2015 at 10:04 PM, Duncan Cross <[hidden email]> wrote:
> languages. My understanding is that keeping this strict division
> between expression and statement is part of the simplicity that Lua
> needs to keep its parser as fast as possible.

I suspect that relaxing this rule would not make the parser much
slower; the simplicity of Lua is intended to help the _human_ parsing
the code. E.g. the famous C/C++ mistake 'if (a = b)' is not possible.
Code is easier to read when there aren't too many possible surprises.


Reply | Threaded
Open this post in threaded view
|

Re: Assignment in C++ like DSL

Dirk Laurie-2
2015-12-26 8:55 GMT+02:00 Abhijit Nandy <[hidden email]>:

>> I suspect that relaxing this rule would not make the parser much
>> slower; the simplicity of Lua is intended to help the _human_ parsing
>> the code. E.g. the famous C/C++ mistake 'if (a = b)' is not possible.
>> Code is easier to read when there aren't too many possible surprises.
>
>
> Lets says speed was not much of an issue, then what modifications would be
> needed to have assignment as an operator in tables.
>
> So if there is say, an __assign() meta-function present in a table, then
> that is called with the value being assigned.
>
> Also C++ allows references on the left hand side of an assignment statement.
> So a function which returns a reference can have a value assigned to the
> returned variable.

Lua has names and values. An assignment statement is nothing
else than the association of a name with a value. Lua does not
have references.

If you wish to understand Lua, forget everything you know about
every other language you have ever used. Particularly C++ and
Python. The closer to Lua that some concept may seem, the more
confusing it becomes.

> If this were present in Lua then having an assignment to the result of a
> function call would be really easy. Since tables are passed by reference

This statement is a good example of the sort of misunderstanding
that come from knowing too much C++ and too little Lua.

Everything in Lua is a TValue structure. In the case of simple,
fixed-length objects like booleans and numbers, the actual data
is stored in the structure itself. In the case of mutable or variable-length
objects like strings, tables and userdata, a pointer to the object is
passed.

> a function could return the table. Then the assignment operator
> could be invoked on it.

There is no such thing as an assignment operator. There is
an assignment statement. Even that name is not used in the
syntax definition, all it says is that

    varlist ‘=’ explist
    local namelist [‘=’ explist]

are possible forms of a statement.

> local tbl = {}
> tbl.value = 0
>
> mt = { __assign(value) = function(value) tbl.value = value end}

The above is total gibberish.

'__assign(value)' in some way suggests that 'value' is a parameter,
but in 'function(value) tbl.value = value end' the field name 'value'
and the parameter 'value' both appear.

Listen, Abhijit. Three experienced and very friendly members
of the Lua community have told you in the nicest possible way
that your idea is crazy and incompatible with Lua. You have
come back with yes-buts every time. This is not acceptable.
Rather divert your obvious energy and enthusiasm into a study
of the Lua API. Once you understand what makes the Lua engine
tick, you will be in a better position to tune it.

Reply | Threaded
Open this post in threaded view
|

Re: Assignment in C++ like DSL

Abhijit Nandy
Thank you Dirk for the detailed explanation :)

Abhijit

On Sat, Dec 26, 2015 at 1:53 PM, Dirk Laurie <[hidden email]> wrote:
2015-12-26 8:55 GMT+02:00 Abhijit Nandy <[hidden email]>:
>> I suspect that relaxing this rule would not make the parser much
>> slower; the simplicity of Lua is intended to help the _human_ parsing
>> the code. E.g. the famous C/C++ mistake 'if (a = b)' is not possible.
>> Code is easier to read when there aren't too many possible surprises.
>
>
> Lets says speed was not much of an issue, then what modifications would be
> needed to have assignment as an operator in tables.
>
> So if there is say, an __assign() meta-function present in a table, then
> that is called with the value being assigned.
>
> Also C++ allows references on the left hand side of an assignment statement.
> So a function which returns a reference can have a value assigned to the
> returned variable.

Lua has names and values. An assignment statement is nothing
else than the association of a name with a value. Lua does not
have references.

If you wish to understand Lua, forget everything you know about
every other language you have ever used. Particularly C++ and
Python. The closer to Lua that some concept may seem, the more
confusing it becomes.

> If this were present in Lua then having an assignment to the result of a
> function call would be really easy. Since tables are passed by reference

This statement is a good example of the sort of misunderstanding
that come from knowing too much C++ and too little Lua.

Everything in Lua is a TValue structure. In the case of simple,
fixed-length objects like booleans and numbers, the actual data
is stored in the structure itself. In the case of mutable or variable-length
objects like strings, tables and userdata, a pointer to the object is
passed.

> a function could return the table. Then the assignment operator
> could be invoked on it.

There is no such thing as an assignment operator. There is
an assignment statement. Even that name is not used in the
syntax definition, all it says is that

    varlist ‘=’ explist
    local namelist [‘=’ explist]

are possible forms of a statement.

> local tbl = {}
> tbl.value = 0
>
> mt = { __assign(value) = function(value) tbl.value = value end}

The above is total gibberish.

'__assign(value)' in some way suggests that 'value' is a parameter,
but in 'function(value) tbl.value = value end' the field name 'value'
and the parameter 'value' both appear.

Listen, Abhijit. Three experienced and very friendly members
of the Lua community have told you in the nicest possible way
that your idea is crazy and incompatible with Lua. You have
come back with yes-buts every time. This is not acceptable.
Rather divert your obvious energy and enthusiasm into a study
of the Lua API. Once you understand what makes the Lua engine
tick, you will be in a better position to tune it.