diff options
author | Eugene Sandulenko | 2019-12-20 16:21:01 +0100 |
---|---|---|
committer | Eugene Sandulenko | 2019-12-20 19:40:53 +0100 |
commit | e972d5109f4512d31f44e372d07028ff4def20b6 (patch) | |
tree | d3b7476928a073250cbddc1e116f2f7f4646cc2b /engines/director/lingo | |
parent | bd1c0add82be392ee63fdc2cc0d37b13a4d66c3c (diff) | |
download | scummvm-rg350-e972d5109f4512d31f44e372d07028ff4def20b6.tar.gz scummvm-rg350-e972d5109f4512d31f44e372d07028ff4def20b6.tar.bz2 scummvm-rg350-e972d5109f4512d31f44e372d07028ff4def20b6.zip |
DIRECTOR: LINGO: Match local arguments during parsing
Diffstat (limited to 'engines/director/lingo')
-rw-r--r-- | engines/director/lingo/lingo-codegen.cpp | 8 | ||||
-rw-r--r-- | engines/director/lingo/lingo-lex.cpp | 27 | ||||
-rw-r--r-- | engines/director/lingo/lingo-lex.l | 9 | ||||
-rw-r--r-- | engines/director/lingo/lingo.h | 3 |
4 files changed, 38 insertions, 9 deletions
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp index c00e2faa1a..284f5ed66b 100644 --- a/engines/director/lingo/lingo-codegen.cpp +++ b/engines/director/lingo/lingo-codegen.cpp @@ -317,6 +317,14 @@ int Lingo::codeArray(int arraySize) { return _currentScript->size(); } +bool Lingo::isInArgStack(Common::String *s) { + for (int i = 0; i < _argstack.size(); i++) + if (_argstack[i]->equalsIgnoreCase(*s)) + return true; + + return false; +} + void Lingo::codeArg(Common::String *s) { _argstack.push_back(s); } diff --git a/engines/director/lingo/lingo-lex.cpp b/engines/director/lingo/lingo-lex.cpp index 336cfdd40c..38b3da6bbe 100644 --- a/engines/director/lingo/lingo-lex.cpp +++ b/engines/director/lingo/lingo-lex.cpp @@ -1538,6 +1538,15 @@ YY_RULE_SETUP if (g_lingo->_ignoreMe && yylval.s->equalsIgnoreCase("me")) return ID; + // When we are defining arguments, allow any string + if (g_lingo->_indef == kStateInArgs) + return ID; + + // First of all, match against argument list + if (g_lingo->_indef == kStateInDef) + if (g_lingo->isInArgStack(yylval.s)) + return ID; + if (g_lingo->_twoWordBuiltins.contains(yytext)) return TWOWORDBUILTIN; @@ -1579,41 +1588,41 @@ YY_RULE_SETUP YY_BREAK case 68: YY_RULE_SETUP -#line 336 "engines/director/lingo/lingo-lex.l" +#line 345 "engines/director/lingo/lingo-lex.l" { count(); yylval.f = atof(yytext); return FLOAT; } YY_BREAK case 69: YY_RULE_SETUP -#line 337 "engines/director/lingo/lingo-lex.l" +#line 346 "engines/director/lingo/lingo-lex.l" { count(); yylval.i = strtol(yytext, NULL, 10); return INT; } YY_BREAK case 70: YY_RULE_SETUP -#line 338 "engines/director/lingo/lingo-lex.l" +#line 347 "engines/director/lingo/lingo-lex.l" { count(); return *yytext; } YY_BREAK case 71: /* rule 71 can match eol */ YY_RULE_SETUP -#line 339 "engines/director/lingo/lingo-lex.l" +#line 348 "engines/director/lingo/lingo-lex.l" { count(); return '\n'; } YY_BREAK case 72: YY_RULE_SETUP -#line 340 "engines/director/lingo/lingo-lex.l" +#line 349 "engines/director/lingo/lingo-lex.l" { count(); yylval.s = new Common::String(&yytext[1]); yylval.s->deleteLastChar(); return STRING; } YY_BREAK case 73: YY_RULE_SETUP -#line 341 "engines/director/lingo/lingo-lex.l" +#line 350 "engines/director/lingo/lingo-lex.l" { count(); } YY_BREAK case 74: YY_RULE_SETUP -#line 343 "engines/director/lingo/lingo-lex.l" +#line 352 "engines/director/lingo/lingo-lex.l" ECHO; YY_BREAK -#line 1617 "engines/director/lingo/lingo-lex.cpp" +#line 1626 "engines/director/lingo/lingo-lex.cpp" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -2573,7 +2582,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 343 "engines/director/lingo/lingo-lex.l" +#line 352 "engines/director/lingo/lingo-lex.l" diff --git a/engines/director/lingo/lingo-lex.l b/engines/director/lingo/lingo-lex.l index 30b3908b06..22347e28e7 100644 --- a/engines/director/lingo/lingo-lex.l +++ b/engines/director/lingo/lingo-lex.l @@ -295,6 +295,15 @@ whitespace [\t ] if (g_lingo->_ignoreMe && yylval.s->equalsIgnoreCase("me")) return ID; + // When we are defining arguments, allow any string + if (g_lingo->_indef == kStateInArgs) + return ID; + + // First of all, match against argument list + if (g_lingo->_indef == kStateInDef) + if (g_lingo->isInArgStack(yylval.s)) + return ID; + if (g_lingo->_twoWordBuiltins.contains(yytext)) return TWOWORDBUILTIN; diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h index 1f0ffd27c0..f17f16478a 100644 --- a/engines/director/lingo/lingo.h +++ b/engines/director/lingo/lingo.h @@ -560,6 +560,9 @@ public: Datum getTheCast(Datum &id, int field); public: + bool isInArgStack(Common::String *s); + +public: ScriptType _currentScriptType; uint16 _currentEntityId; ScriptContext *_currentScriptContext; |