loopier / animatron

Animatron for Godot 4.x <
15 stars 1 forks source link

`/def` problems: parsing and variable substitution #19

Open loopier opened 8 months ago

loopier commented 8 months ago

/def was not working properly because it's CommandDescription is actually not a CommandDescription. It's a Dictionary with 2 keys: variables and subcommands. They need special treatment in Main.evalCommand(). See https://github.com/loopier/animatron/commit/345d173938cf4df87855ebb33345d478128909ba

I think we agreed that the actual /def command was to be handled by CommandInterface and it's parsing prior to execution by OCL, but I'm not 100% sure. Can you confirm this?

If this is the case, /def won't work until we have some kind of working OCL that can parse the variables and return proper commands.

totalgee commented 8 months ago

I think we agreed that the actual /def command was to be handled by CommandInterface and it's parsing prior to execution by OCL, but I'm not 100% sure. Can you confirm this?

image

I don't totally recall... From the diagram we drew on the board there is an arrow going from Main to OCL, but there is also a signal arrow going up from def (under Main) back up to Main (I think this means the defs are broken down recursively into simple "core" commands that don't include any defs). I think the def processing should happen first, breaking everything down as far as possible, and then before each core command is executed it should be evaluated by OCL.

/def won't work until we have some kind of working OCL that can parse the variables and return proper commands.

Feel free to add a stub function in OCL that just returns what it receives. Then I will implement the { expr } parsing part and ensure /for loops work.

loopier commented 8 months ago

As I see it there are 2 different stages for a /def, its definition and its usage. Usage has 2 more stages: parsing and execution. Main should probably handle definition and execution but parsing should be handled by OCL because there might be expressions in the def subcommands, not only variables.

For example:

/def /bla x y
  /create $x default
  /scale $x $y

Stage A - definition

Main takes care of the definition:

  1. Main receives /def bla x y ... (the actual /def command, not the /bla command)
  2. Main adds it to the defCommands dictionary:
    defCmds = {
    "/bla": { 
    "variables": [x,y], 
    "subcommands": [
      [/create $x default],
      [/scale $x $y]
    ]
    }
    }

Stage B - usage

Stage B.1 - reception

  1. Main receives /bla ma 2
  2. Main looks up the CommandDescription which returns not an actual CommandDescription but a Dictionary with: { "variables": [x,y], "subcommands": [[/create $x default],[/scale $x $y]]}.

Stage B.2 - parsing

  1. Main sends the Dictionary and the command aguments (e.g. ["ma", 2]) to OCL
  2. OCL returns an array of core commands: [[/create ma default],[/scale ma 2]]

Stage B.3 - execution

  1. Main loops the commands array and executes them one at a time
totalgee commented 8 months ago

Thanks, this is good and clear. One missing piece is in B.2, point 1. It should read:

  1. Main sends the Dictionary and the command arguments (e.g. ["ma", 2]) to OCL

For some reason I thought you'd wanted the def evaluation/expansion to also be in Main, but it makes sense for it to be in OCL. Just add a stub command taking the arguments you want to send to OCL (defCommand: Dictionary and args: Array I guess), and I will start to fill it in with the proper behaviour.

loopier commented 8 months ago

I just found out that it was already there: OpenControlLanguage._def(...)

I can use it as stub for /def and makes /defs actually work -- without variables, which needs to be done.

One missing piece is in B.2, point 1. It should read:

1. `Main` sends the `Dictionary` **and the command arguments** (e.g. `["ma", 2]`) to `OCL`

Fixed it in my comment