Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parser modification #1

Open
N1ceL opened this issue May 13, 2021 · 6 comments
Open

Parser modification #1

N1ceL opened this issue May 13, 2021 · 6 comments

Comments

@N1ceL
Copy link

N1ceL commented May 13, 2021

Hello, I really liked the idea of making the strongest scripting language (jit/ffi turns the language into a better one) with normal syntax. I've already fixed '++', '--' bug (not working without ';'), made arrays from 0, and etc. But for the perfect language I want to make 'for' like on JS/C++, but I do not know how to fix the problem is that the loop works incorrectly.

Parser 'for' code:

static void parse_for_new(LexState* ls, BCLine line)
{
    FuncState* fs = ls->fs;
    BCPos start, loop, condexit;
    FuncScope bl;
    lj_lex_next(ls);  /* Skip 'while'. */
    lex_check(ls, '(');
    parse_local(ls);
    lex_check(ls, ';');
    start = fs->lasttarget = fs->pc;
    condexit = expr_cond(ls);
    lex_check(ls, ';');
    parse_block(ls);
    lex_check(ls, ')');
    fscope_begin(fs, &bl, FSCOPE_LOOP);
    loop = bcemit_AD(fs, BC_LOOP, fs->nactvar, 0);
    parse_block(ls);
    jmp_patch(fs, bcemit_jmp(fs), start);
    fscope_end(fs);
    jmp_tohere(fs, condexit);
    jmp_patchins(fs, loop, fs->pc);
}

Here is a screenshot with the problem, the value changes between the 'for' check and the main block:
image

I do not know how to make a 'value change block' after 'main block'

@mingodad
Copy link
Owner

Can you share your project to see the whole thing ?

@N1ceL
Copy link
Author

N1ceL commented May 13, 2021

Created a repository, but temporarily I had to disable the second 'for' type (with 'in') because the problems with creating a variable in block between '(', ';'

@mingodad
Copy link
Owner

I'm looking at it now.

@mingodad
Copy link
Owner

It seems that the problem is that you are parsing then third parameter of the for statement but not skiping it when entering the loop, somehow you'll need add some jumps or reorder the generated code.

static void parse_for_new(LexState* ls, BCLine line)
{
    FuncState* fs = ls->fs;
    BCPos start, loop, condexit;
    FuncScope bl;
    lj_lex_next(ls);  /* Skip 'while'. */
    lex_check(ls, '(');
    parse_local(ls);
    lex_check(ls, ';');
    start = fs->lasttarget = fs->pc;
    condexit = expr_cond(ls);
    lex_check(ls, ';');
    parse_block(ls); ////!!!! this code block should be moved to the end of the loop
    lex_check(ls, ')');
    fscope_begin(fs, &bl, FSCOPE_LOOP);
    loop = bcemit_AD(fs, BC_LOOP, fs->nactvar, 0);
    parse_block(ls);
    jmp_patch(fs, bcemit_jmp(fs), start);
    fscope_end(fs);
    jmp_tohere(fs, condexit);
    jmp_patchins(fs, loop, fs->pc);
}

@N1ceL
Copy link
Author

N1ceL commented May 13, 2021

The problem is that I have no idea how to do it. Parsing is sequential, I don't know how to skip this block, and then go back to register it.

In Jual 'for' block with JS syntax looks like this: https://github.com/sajonoso/jual/blob/master/src/lparser.c#L1654-L1683
But how to make it on LuaJIT, I have no idea.

Anyway thank you for your time.

@mingodad
Copy link
Owner

Should be very similar, why not you try first with ljs following Jual then you go back to Ljslit, the jumps and lables are there:

  checknext(ls, ';');
  condinit = luaK_getlabel(fs); //creating a label for goto ?
  condexit = cond(ls);
  checknext(ls, ';');
  blockinit = luaK_jump(fs); // doing the goto ?
  stepinit = luaK_getlabel(fs); //creating another label
  statement(ls);
  stepexit = luaK_jump(fs); //anther goto
  checknext(ls, ')');
  checknext(ls, '{');
  luaK_patchtohere(fs, blockinit); //doing fixups
  block(ls);
  (void)luaK_getlabel(fs);
  luaK_jumpto(fs, stepinit); //goto
  luaK_patchtohere(fs, stepexit); 
  luaK_jumpto(fs, condinit); //goto
  check_match(ls, '}', TK_FOR, line);
  leaveblock(fs);
  luaK_patchtohere(fs, condexit); //adjusting the label address ?

@N1ceL N1ceL changed the title Help with code modification Parser modification May 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants