From 70a7abacbb36783fb77025814242faf32a6c8a47 Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Mon, 10 Jun 2024 15:01:41 -0300 Subject: Fix parsing of certain constructs --- src/cratera/compiler.lua | 29 +++++++++++++++++++++++------ test/tests.cratera | 12 ++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/cratera/compiler.lua b/src/cratera/compiler.lua index 6b188ef..5e9b0b5 100644 --- a/src/cratera/compiler.lua +++ b/src/cratera/compiler.lua @@ -171,6 +171,7 @@ defs[parser.FALLBACK] = function(state, token) elseif results[i-2] == TK.FUNCTION then -- we're in funcname -- funcname is of the form Name {'.' Name} ':' -- TODO how can we parse 'function Foo:[Bar].Baz()'... + -- oh we think we need a real compiler for that find_statement = false break else @@ -194,6 +195,7 @@ defs[parser.FALLBACK] = function(state, token) while true do i = ignore_newlines(results, i) if is_tk(results, i, ')') then + local j = i -- (prefixexp) or (funcargs) -- find matching '(' local depth = 1 @@ -207,6 +209,11 @@ defs[parser.FALLBACK] = function(state, token) error("syntax error (unbalanced '()')") end until depth == 0 + if results[i - 1] == TK.FUNCTION then + i = j + -- found start + break + end elseif is_tk(results, i, ']') then -- [indexing] -- find matching '[' @@ -225,12 +232,13 @@ defs[parser.FALLBACK] = function(state, token) -- Name or '.' Name i = i - 2 i = ignore_newlines(results, i) - if is_tk(results, i, '.') then - -- skip '.' - i = i - 1 - else - -- found start of statement - break + if not is_tk(results, i, '.') then + if results[i] == TK.FUNCTION then + i = i + 1 + else + -- found start of statement + break + end end elseif is_tk(results, i, '}') then -- prefixexp '{' table '}' @@ -276,6 +284,14 @@ defs[parser.FALLBACK] = function(state, token) error("syntax error") end else + if results[i] == TK.FUNCTION then + -- 'function' Name (funcargs) + -- 'function' Name '.' Name (funcargs) + -- etc + repeat + i = i + 1 + until results[i] == ')' or not results[i] + end -- found start of statement break end @@ -289,6 +305,7 @@ defs[parser.FALLBACK] = function(state, token) for k=i, #results do if results[k] == END_OF_STMT then local v = results[k+1] + assert(v > i) if v > i then -- this should always be true? results[k+1] = v + 1 end diff --git a/test/tests.cratera b/test/tests.cratera index fd97917..8977b74 100644 --- a/test/tests.cratera +++ b/test/tests.cratera @@ -9,6 +9,7 @@ t[T] = t t.f = print t.ff = print t.g = function(self, a) print(self, a[1]) end +t.h = function(self, v) return v end t[F] = print local _f="f" local _t="t" @@ -48,6 +49,17 @@ _=(t:[_t].f(11)) -- inside () t:[_t].g {12} -- table call t:[_t].f "13" -- string call +;(function()return t end)():[(function() return t:[(function()return"t"end)()].h("t") end)()].f(14) -- function using traits in trait key +;(function()return t end)():[(function() return (function()return t end)():[(function()return"t"end)()].h("t") end)()].f(15) -- function using traits in trait key +local function call_f(v) + (function()return t end)():["t"].f(v) +end +call_f(16) +call_f = function(v) + (function()return t end)():["t"].f(v) +end +call_f(17) +;t.t.t.t.h(t, t):["t"].f(18) entity = {} -- cgit 1.4.1