diff options
author | Eugene Sandulenko | 2016-06-19 18:52:07 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2016-08-03 23:40:36 +0200 |
commit | 81b056ffc1670dba3e46c42eb5d16263ab724f6e (patch) | |
tree | 1e4786034be01e13a07562c1370dc6723dc281c1 | |
parent | 4a536c57f1012c0bb4380d84ddc2ee72c3f3d332 (diff) | |
download | scummvm-rg350-81b056ffc1670dba3e46c42eb5d16263ab724f6e.tar.gz scummvm-rg350-81b056ffc1670dba3e46c42eb5d16263ab724f6e.tar.bz2 scummvm-rg350-81b056ffc1670dba3e46c42eb5d16263ab724f6e.zip |
DIRECTOR: Lingo: Add missing funcs
-rw-r--r-- | engines/director/director.cpp | 7 | ||||
-rw-r--r-- | engines/director/lingo/lingo-funcs.cpp | 73 | ||||
-rw-r--r-- | engines/director/lingo/lingo-gr.cpp | 176 | ||||
-rw-r--r-- | engines/director/lingo/lingo-gr.h | 46 | ||||
-rw-r--r-- | engines/director/lingo/lingo-gr.y | 4 | ||||
-rw-r--r-- | engines/director/lingo/lingo-lex.cpp | 36 | ||||
-rw-r--r-- | engines/director/lingo/lingo-lex.l | 3 | ||||
-rw-r--r-- | engines/director/lingo/lingo.cpp | 10 | ||||
-rw-r--r-- | engines/director/lingo/lingo.h | 11 | ||||
-rw-r--r-- | engines/director/module.mk | 2 |
10 files changed, 230 insertions, 138 deletions
diff --git a/engines/director/director.cpp b/engines/director/director.cpp index fa3a4096f7..fccd3b545b 100644 --- a/engines/director/director.cpp +++ b/engines/director/director.cpp @@ -79,10 +79,13 @@ Common::Error DirectorEngine::run() { _lingo->addCode("set x = 1 + 3\n\ set y to 2 + 3 * 2 -- this set y to 4\n\ put 5 into z\n\ --- some more\n", kMovieScript, 2); +-- some more\n\ +x\n\ +y\n\ +z\n", kMovieScript, 2); _lingo->addCode("2 + 3 * 2 / (5 - 2)", kMovieScript, 3); - _lingo->executeScript(kMovieScript, 3); + _lingo->executeScript(kMovieScript, 1); //FIXME _mainArchive = new RIFFArchive(); diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp index b28e709166..71d1844cab 100644 --- a/engines/director/lingo/lingo-funcs.cpp +++ b/engines/director/lingo/lingo-funcs.cpp @@ -24,7 +24,10 @@ #include "common/file.h" #include "audio/decoders/wave.h" +#include "director/lingo/lingo-gr.h" + namespace Director { + enum MCITokenType { kMCITokenNone, @@ -186,7 +189,7 @@ void Lingo::func_xpop() { void Lingo::func_printtop(void) { Datum d = g_lingo->pop(); - warning("%d\n", d.val); + warning("%d", d.val); } void Lingo::func_constpush() { @@ -197,12 +200,70 @@ void Lingo::func_constpush() { } void Lingo::func_varpush() { + Datum d; + Symbol *sym; + char *name = (char *)g_lingo->_pc; + + if (!g_lingo->_vars.contains(name)) { // Create variable if it was not defined + sym = new Symbol; + sym->name = (char *)calloc(strlen(name) + 1, 1); + Common::strlcpy(sym->name, name, strlen(name) + 1); + sym->type = UNDEF; + sym->u.val = 0; + + g_lingo->_vars[name] = sym; + } else { + sym = g_lingo->_vars[name]; + } + + d.sym = sym; + + g_lingo->_pc += g_lingo->calcStringAlignment(name); + + g_lingo->push(d); } void Lingo::func_assign() { + Datum d1, d2; + d1 = g_lingo->pop(); + d2 = g_lingo->pop(); + + if (d1.sym->type != VAR && d1.sym->type != UNDEF) { + warning("assignment to non-variable '%s'", d1.sym->name); + return; + } + + d1.sym->u.val = d2.val; + d1.sym->type = VAR; + g_lingo->push(d2); +} + +bool Lingo::verify(Symbol *s) { + if (s->type != VAR && s->type != UNDEF) { + warning("attempt to evaluate non-variable '%s'", s->name); + + return false; + } + + if (s->type == UNDEF) { + warning("undefined variable '%s'", s->name); + + return false; + } + + return true; } void Lingo::func_eval() { + Datum d; + d = g_lingo->pop(); + + if (!g_lingo->verify(d.sym)) + return; + + d.val = d.sym->u.val; + + g_lingo->push(d); } void Lingo::func_add() { @@ -249,9 +310,19 @@ void Lingo::func_negate() { } void Lingo::func_mci() { + Common::String s((char *)g_lingo->_pc); + + g_lingo->exec_mci(&s); + + g_lingo->_pc += g_lingo->calcStringAlignment(s.c_str()); } void Lingo::func_mciwait() { + Common::String s((char *)g_lingo->_pc); + + g_lingo->exec_mciwait(&s); + + g_lingo->_pc += g_lingo->calcStringAlignment(s.c_str()); } } diff --git a/engines/director/lingo/lingo-gr.cpp b/engines/director/lingo/lingo-gr.cpp index b6874ecfc6..ad7104c127 100644 --- a/engines/director/lingo/lingo-gr.cpp +++ b/engines/director/lingo/lingo-gr.cpp @@ -67,30 +67,32 @@ know about them. */ enum yytokentype { UNARY = 258, - INT = 259, - FLOAT = 260, - VAR = 261, - STRING = 262, - OP_INTO = 263, - OP_TO = 264, - FUNC_MCI = 265, - FUNC_MCIWAIT = 266, - FUNC_PUT = 267, - FUNC_SET = 268 + UNDEF = 259, + INT = 260, + FLOAT = 261, + VAR = 262, + STRING = 263, + OP_INTO = 264, + OP_TO = 265, + FUNC_MCI = 266, + FUNC_MCIWAIT = 267, + FUNC_PUT = 268, + FUNC_SET = 269 }; #endif /* Tokens. */ #define UNARY 258 -#define INT 259 -#define FLOAT 260 -#define VAR 261 -#define STRING 262 -#define OP_INTO 263 -#define OP_TO 264 -#define FUNC_MCI 265 -#define FUNC_MCIWAIT 266 -#define FUNC_PUT 267 -#define FUNC_SET 268 +#define UNDEF 259 +#define INT 260 +#define FLOAT 261 +#define VAR 262 +#define STRING 263 +#define OP_INTO 264 +#define OP_TO 265 +#define FUNC_MCI 266 +#define FUNC_MCIWAIT 267 +#define FUNC_PUT 268 +#define FUNC_SET 269 @@ -105,8 +107,6 @@ #include "director/lingo/lingo.h" #include "director/lingo/lingo-gr.h" -Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> vars; - extern int yylex(); extern int yyparse(); void yyerror(char *s) { warning("%s", s); } @@ -135,7 +135,7 @@ using namespace Director; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 43 "engines/director/lingo/lingo-gr.y" +#line 41 "engines/director/lingo/lingo-gr.y" { Common::String *s; int i; @@ -374,7 +374,7 @@ union yyalloc #define YYLAST 52 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 23 +#define YYNTOKENS 24 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 7 /* YYNRULES -- Number of rules. */ @@ -384,7 +384,7 @@ union yyalloc /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 268 +#define YYMAXUTOK 269 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -393,12 +393,12 @@ union yyalloc static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 19, 2, 2, - 21, 22, 17, 15, 2, 16, 2, 18, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 20, 2, 2, + 22, 23, 18, 16, 2, 17, 2, 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 14, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -418,7 +418,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13 + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; #if YYDEBUG @@ -434,22 +434,22 @@ static const yytype_uint8 yyprhs[] = /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 24, 0, -1, 25, 20, 24, -1, 25, -1, -1, - 29, -1, 26, -1, 27, -1, 28, -1, -1, 12, - 28, 8, 6, -1, 13, 6, 14, 28, -1, 13, - 6, 9, 28, -1, 28, -1, 4, -1, 6, -1, - 28, 15, 28, -1, 28, 16, 28, -1, 28, 17, - 28, -1, 28, 18, 28, -1, 15, 28, -1, 16, - 28, -1, 21, 28, 22, -1, 10, 7, -1, 11, - 6, -1 + 25, 0, -1, 26, 21, 25, -1, 26, -1, -1, + 30, -1, 27, -1, 28, -1, 29, -1, -1, 13, + 29, 9, 7, -1, 14, 7, 15, 29, -1, 14, + 7, 10, 29, -1, 29, -1, 5, -1, 7, -1, + 29, 16, 29, -1, 29, 17, 29, -1, 29, 18, + 29, -1, 29, 19, 29, -1, 16, 29, -1, 17, + 29, -1, 22, 29, 23, -1, 11, 8, -1, 12, + 7, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 70, 70, 71, 74, 75, 76, 77, 78, 79, - 82, 83, 84, 87, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 101, 102 + 0, 68, 68, 69, 72, 73, 74, 75, 76, 77, + 80, 81, 82, 85, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 99, 100 }; #endif @@ -458,11 +458,11 @@ static const yytype_uint8 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "UNARY", "INT", "FLOAT", "VAR", "STRING", - "OP_INTO", "OP_TO", "FUNC_MCI", "FUNC_MCIWAIT", "FUNC_PUT", "FUNC_SET", - "'='", "'+'", "'-'", "'*'", "'/'", "'%'", "'\\n'", "'('", "')'", - "$accept", "program", "programline", "assign", "statement", "expr", - "func", 0 + "$end", "error", "$undefined", "UNARY", "UNDEF", "INT", "FLOAT", "VAR", + "STRING", "OP_INTO", "OP_TO", "FUNC_MCI", "FUNC_MCIWAIT", "FUNC_PUT", + "FUNC_SET", "'='", "'+'", "'-'", "'*'", "'/'", "'%'", "'\\n'", "'('", + "')'", "$accept", "program", "programline", "assign", "statement", + "expr", "func", 0 }; #endif @@ -472,17 +472,17 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 61, 43, 45, 42, 47, 37, - 10, 40, 41 + 265, 266, 267, 268, 269, 61, 43, 45, 42, 47, + 37, 10, 40, 41 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 23, 24, 24, 25, 25, 25, 25, 25, 25, - 26, 26, 26, 27, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 29, 29 + 0, 24, 25, 25, 26, 26, 26, 26, 26, 26, + 27, 27, 27, 28, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 30, 30 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -513,20 +513,20 @@ static const yytype_int8 yydefgoto[] = /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -9 +#define YYPACT_NINF -10 static const yytype_int8 yypact[] = { - 3, -9, -9, -2, 2, 23, 6, 23, 23, 23, - 17, 8, -9, -9, 19, -9, -9, -9, 25, -8, - -9, -9, 30, -9, 3, 23, 23, 23, 23, 24, - 23, 23, -9, -9, -7, -7, -9, -9, -9, 19, - 19 + 2, -10, -10, -3, 1, 22, 5, 22, 22, 22, + 17, 7, -10, -10, 18, -10, -10, -10, 24, -9, + -10, -10, 29, -10, 2, 22, 22, 22, 22, 23, + 22, 22, -10, -10, -8, -8, -10, -10, -10, 18, + 18 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -9, 7, -9, -9, -9, -5, -9 + -10, 8, -10, -10, -10, -5, -10 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -539,30 +539,30 @@ static const yytype_uint8 yytable[] = 18, 30, 20, 21, 22, 16, 31, 1, 17, 2, 27, 28, 19, 3, 4, 5, 6, 23, 7, 8, 34, 35, 36, 37, 9, 39, 40, 1, 24, 2, - 38, 33, 0, 29, 25, 26, 27, 28, 7, 8, + 38, 0, 33, 29, 25, 26, 27, 28, 7, 8, 25, 26, 27, 28, 9, 25, 26, 27, 28, 0, 0, 0, 32 }; static const yytype_int8 yycheck[] = { - 5, 9, 7, 8, 9, 7, 14, 4, 6, 6, - 17, 18, 6, 10, 11, 12, 13, 0, 15, 16, - 25, 26, 27, 28, 21, 30, 31, 4, 20, 6, - 6, 24, -1, 8, 15, 16, 17, 18, 15, 16, - 15, 16, 17, 18, 21, 15, 16, 17, 18, -1, - -1, -1, 22 + 5, 10, 7, 8, 9, 8, 15, 5, 7, 7, + 18, 19, 7, 11, 12, 13, 14, 0, 16, 17, + 25, 26, 27, 28, 22, 30, 31, 5, 21, 7, + 7, -1, 24, 9, 16, 17, 18, 19, 16, 17, + 16, 17, 18, 19, 22, 16, 17, 18, 19, -1, + -1, -1, 23 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 4, 6, 10, 11, 12, 13, 15, 16, 21, - 24, 25, 26, 27, 28, 29, 7, 6, 28, 6, - 28, 28, 28, 0, 20, 15, 16, 17, 18, 8, - 9, 14, 22, 24, 28, 28, 28, 28, 6, 28, - 28 + 0, 5, 7, 11, 12, 13, 14, 16, 17, 22, + 25, 26, 27, 28, 29, 30, 8, 7, 29, 7, + 29, 29, 29, 0, 21, 16, 17, 18, 19, 9, + 10, 15, 23, 25, 29, 29, 29, 29, 7, 29, + 29 }; #define yyerrok (yyerrstatus = 0) @@ -1377,87 +1377,87 @@ yyreduce: switch (yyn) { case 6: -#line 76 "engines/director/lingo/lingo-gr.y" +#line 74 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_xpop); ;} break; case 8: -#line 78 "engines/director/lingo/lingo-gr.y" +#line 76 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_printtop); ;} break; case 10: -#line 82 "engines/director/lingo/lingo-gr.y" +#line 80 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_varpush); g_lingo->codeString((yyvsp[(4) - (4)].s)->c_str()); g_lingo->code1(g_lingo->func_assign); (yyval.code) = (yyvsp[(2) - (4)].code); delete (yyvsp[(4) - (4)].s); ;} break; case 11: -#line 83 "engines/director/lingo/lingo-gr.y" +#line 81 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_varpush); g_lingo->codeString((yyvsp[(2) - (4)].s)->c_str()); g_lingo->code1(g_lingo->func_assign); (yyval.code) = (yyvsp[(4) - (4)].code); delete (yyvsp[(2) - (4)].s); ;} break; case 12: -#line 84 "engines/director/lingo/lingo-gr.y" +#line 82 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_varpush); g_lingo->codeString((yyvsp[(2) - (4)].s)->c_str()); g_lingo->code1(g_lingo->func_assign); (yyval.code) = (yyvsp[(4) - (4)].code); delete (yyvsp[(2) - (4)].s); ;} break; case 13: -#line 87 "engines/director/lingo/lingo-gr.y" +#line 85 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_xpop); ;} break; case 14: -#line 90 "engines/director/lingo/lingo-gr.y" +#line 88 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_constpush); inst i; WRITE_LE_UINT32(&i, (yyvsp[(1) - (1)].i)); (yyval.code) = g_lingo->code1(i); ;} break; case 15: -#line 91 "engines/director/lingo/lingo-gr.y" +#line 89 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_varpush); g_lingo->codeString((yyvsp[(1) - (1)].s)->c_str()); (yyval.code) = g_lingo->code1(g_lingo->func_eval); delete (yyvsp[(1) - (1)].s); ;} break; case 16: -#line 92 "engines/director/lingo/lingo-gr.y" +#line 90 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_add); ;} break; case 17: -#line 93 "engines/director/lingo/lingo-gr.y" +#line 91 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_sub); ;} break; case 18: -#line 94 "engines/director/lingo/lingo-gr.y" +#line 92 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_mul); ;} break; case 19: -#line 95 "engines/director/lingo/lingo-gr.y" +#line 93 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_div); ;} break; case 20: -#line 96 "engines/director/lingo/lingo-gr.y" +#line 94 "engines/director/lingo/lingo-gr.y" { (yyval.code) = (yyvsp[(2) - (2)].code); ;} break; case 21: -#line 97 "engines/director/lingo/lingo-gr.y" +#line 95 "engines/director/lingo/lingo-gr.y" { (yyval.code) = (yyvsp[(2) - (2)].code); g_lingo->code1(g_lingo->func_negate); ;} break; case 22: -#line 98 "engines/director/lingo/lingo-gr.y" +#line 96 "engines/director/lingo/lingo-gr.y" { (yyval.code) = (yyvsp[(2) - (3)].code); ;} break; case 23: -#line 101 "engines/director/lingo/lingo-gr.y" +#line 99 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_mci); g_lingo->codeString((yyvsp[(2) - (2)].s)->c_str()); delete (yyvsp[(2) - (2)].s); ;} break; case 24: -#line 102 "engines/director/lingo/lingo-gr.y" +#line 100 "engines/director/lingo/lingo-gr.y" { g_lingo->code1(g_lingo->func_mciwait); g_lingo->codeString((yyvsp[(2) - (2)].s)->c_str()); delete (yyvsp[(2) - (2)].s); ;} break; @@ -1677,6 +1677,6 @@ yyreturn: } -#line 105 "engines/director/lingo/lingo-gr.y" +#line 103 "engines/director/lingo/lingo-gr.y" diff --git a/engines/director/lingo/lingo-gr.h b/engines/director/lingo/lingo-gr.h index ddf0c48180..2de0733d08 100644 --- a/engines/director/lingo/lingo-gr.h +++ b/engines/director/lingo/lingo-gr.h @@ -40,37 +40,39 @@ know about them. */ enum yytokentype { UNARY = 258, - INT = 259, - FLOAT = 260, - VAR = 261, - STRING = 262, - OP_INTO = 263, - OP_TO = 264, - FUNC_MCI = 265, - FUNC_MCIWAIT = 266, - FUNC_PUT = 267, - FUNC_SET = 268 + UNDEF = 259, + INT = 260, + FLOAT = 261, + VAR = 262, + STRING = 263, + OP_INTO = 264, + OP_TO = 265, + FUNC_MCI = 266, + FUNC_MCIWAIT = 267, + FUNC_PUT = 268, + FUNC_SET = 269 }; #endif /* Tokens. */ #define UNARY 258 -#define INT 259 -#define FLOAT 260 -#define VAR 261 -#define STRING 262 -#define OP_INTO 263 -#define OP_TO 264 -#define FUNC_MCI 265 -#define FUNC_MCIWAIT 266 -#define FUNC_PUT 267 -#define FUNC_SET 268 +#define UNDEF 259 +#define INT 260 +#define FLOAT 261 +#define VAR 262 +#define STRING 263 +#define OP_INTO 264 +#define OP_TO 265 +#define FUNC_MCI 266 +#define FUNC_MCIWAIT 267 +#define FUNC_PUT 268 +#define FUNC_SET 269 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 43 "engines/director/lingo/lingo-gr.y" +#line 41 "engines/director/lingo/lingo-gr.y" { Common::String *s; int i; @@ -78,7 +80,7 @@ typedef union YYSTYPE int code; } /* Line 1529 of yacc.c. */ -#line 82 "engines/director/lingo/lingo-gr.hpp" +#line 84 "engines/director/lingo/lingo-gr.hpp" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 diff --git a/engines/director/lingo/lingo-gr.y b/engines/director/lingo/lingo-gr.y index c05e985115..e79fab49b8 100644 --- a/engines/director/lingo/lingo-gr.y +++ b/engines/director/lingo/lingo-gr.y @@ -30,8 +30,6 @@ #include "director/lingo/lingo.h" #include "director/lingo/lingo-gr.h" -Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> vars; - extern int yylex(); extern int yyparse(); void yyerror(char *s) { warning("%s", s); } @@ -47,7 +45,7 @@ using namespace Director; int code; } -%token UNARY +%token UNARY UNDEF %token<i> INT %token<f> FLOAT %token<s> VAR STRING diff --git a/engines/director/lingo/lingo-lex.cpp b/engines/director/lingo/lingo-lex.cpp index 59796ce3f4..8b27c5d9c2 100644 --- a/engines/director/lingo/lingo-lex.cpp +++ b/engines/director/lingo/lingo-lex.cpp @@ -697,7 +697,7 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 44 "engines/director/lingo/lingo-lex.l" +#line 45 "engines/director/lingo/lingo-lex.l" #line 704 "engines/director/lingo/lingo-lex.cpp" @@ -786,83 +786,83 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 46 "engines/director/lingo/lingo-lex.l" +#line 47 "engines/director/lingo/lingo-lex.l" YY_BREAK case 2: YY_RULE_SETUP -#line 47 "engines/director/lingo/lingo-lex.l" +#line 48 "engines/director/lingo/lingo-lex.l" YY_BREAK case 3: YY_RULE_SETUP -#line 48 "engines/director/lingo/lingo-lex.l" +#line 49 "engines/director/lingo/lingo-lex.l" { return ' '; } YY_BREAK case 4: YY_RULE_SETUP -#line 49 "engines/director/lingo/lingo-lex.l" +#line 50 "engines/director/lingo/lingo-lex.l" { return OP_INTO; } YY_BREAK case 5: YY_RULE_SETUP -#line 50 "engines/director/lingo/lingo-lex.l" +#line 51 "engines/director/lingo/lingo-lex.l" { return FUNC_MCI; } YY_BREAK case 6: YY_RULE_SETUP -#line 51 "engines/director/lingo/lingo-lex.l" +#line 52 "engines/director/lingo/lingo-lex.l" { return FUNC_MCIWAIT; } YY_BREAK case 7: YY_RULE_SETUP -#line 52 "engines/director/lingo/lingo-lex.l" +#line 53 "engines/director/lingo/lingo-lex.l" { return FUNC_PUT; } YY_BREAK case 8: YY_RULE_SETUP -#line 53 "engines/director/lingo/lingo-lex.l" +#line 54 "engines/director/lingo/lingo-lex.l" { return FUNC_SET; } YY_BREAK case 9: YY_RULE_SETUP -#line 54 "engines/director/lingo/lingo-lex.l" +#line 55 "engines/director/lingo/lingo-lex.l" { return OP_TO; } YY_BREAK case 10: YY_RULE_SETUP -#line 56 "engines/director/lingo/lingo-lex.l" +#line 57 "engines/director/lingo/lingo-lex.l" { yylval.s = new Common::String(yytext); return VAR; } YY_BREAK case 11: YY_RULE_SETUP -#line 57 "engines/director/lingo/lingo-lex.l" +#line 58 "engines/director/lingo/lingo-lex.l" { yylval.f = atof(yytext); return FLOAT; } YY_BREAK case 12: YY_RULE_SETUP -#line 58 "engines/director/lingo/lingo-lex.l" +#line 59 "engines/director/lingo/lingo-lex.l" { yylval.i = strtol(yytext, NULL, 10); return INT; } YY_BREAK case 13: YY_RULE_SETUP -#line 59 "engines/director/lingo/lingo-lex.l" +#line 60 "engines/director/lingo/lingo-lex.l" { return *yytext; } YY_BREAK case 14: /* rule 14 can match eol */ YY_RULE_SETUP -#line 60 "engines/director/lingo/lingo-lex.l" +#line 61 "engines/director/lingo/lingo-lex.l" { return '\n'; } YY_BREAK case 15: YY_RULE_SETUP -#line 61 "engines/director/lingo/lingo-lex.l" +#line 62 "engines/director/lingo/lingo-lex.l" { yylval.s = new Common::String(&yytext[1]); yylval.s->deleteLastChar(); return STRING; } YY_BREAK case 16: YY_RULE_SETUP -#line 63 "engines/director/lingo/lingo-lex.l" +#line 64 "engines/director/lingo/lingo-lex.l" ECHO; YY_BREAK #line 869 "engines/director/lingo/lingo-lex.cpp" @@ -1865,7 +1865,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 63 "engines/director/lingo/lingo-lex.l" +#line 64 "engines/director/lingo/lingo-lex.l" diff --git a/engines/director/lingo/lingo-lex.l b/engines/director/lingo/lingo-lex.l index 0d8324992b..c49dae956a 100644 --- a/engines/director/lingo/lingo-lex.l +++ b/engines/director/lingo/lingo-lex.l @@ -40,11 +40,12 @@ constinteger [[:digit:]]+ conststring \"[^\"\n]*\" operator [-+*/%=^:,()] newline [\n\r]+ +whitespace [\t ] %% --[^\r\n]* -^[ \t] +^{whitespace} [\t]+ { return ' '; } into { return OP_INTO; } mci { return FUNC_MCI; } diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp index 51d5312a38..1572685bc3 100644 --- a/engines/director/lingo/lingo.cpp +++ b/engines/director/lingo/lingo.cpp @@ -21,6 +21,7 @@ */ #include "director/lingo/lingo.h" +#include "director/lingo/lingo-gr.h" namespace Director { @@ -66,6 +67,12 @@ struct EventHandlerType { { kEventNone, 0 }, }; +Symbol::Symbol() { + name = NULL; + type = UNDEF; + u.str = NULL; +} + Lingo::Lingo(DirectorEngine *vm) : _vm(vm) { g_lingo = this; @@ -82,8 +89,7 @@ Lingo::~Lingo() { } int Lingo::codeString(const char *str) { - int instLen = sizeof(inst); - int numInsts = strlen(str) / instLen + (strlen(str) + 1 + instLen - 1) % instLen; + int numInsts = calcStringAlignment(str); // Where we copy the string over int pos = _currentScript->size(); diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h index fba82a26d7..2da23ce7ba 100644 --- a/engines/director/lingo/lingo.h +++ b/engines/director/lingo/lingo.h @@ -82,11 +82,15 @@ typedef struct Symbol { /* symbol table entry */ inst *defn; /* FUNCTION, PROCEDURE */ char *str; /* STRING */ } u; + + Symbol(); } Symbol; typedef union Datum { /* interpreter stack type */ int val; Symbol *sym; + + Datum() { val = 0; sym = NULL; } } Datum; typedef Common::Array<inst> ScriptData; @@ -108,6 +112,10 @@ public: int code3(inst code_1, inst code_2, inst code_3) { code1(code_1); code1(code_2); return code1(code_3); } int codeString(const char *s); + int calcStringAlignment(const char *s) { + int instLen = sizeof(inst); + int l = strlen(s); return l / instLen + (l + 1 + instLen - 1) % instLen; + } public: static void func_xpop(); @@ -120,6 +128,7 @@ public: static void func_constpush(); static void func_varpush(); static void func_assign(); + bool verify(Symbol *s); static void func_eval(); static void func_mci(); static void func_mciwait(); @@ -137,6 +146,8 @@ private: ScriptHash _scripts[kMaxScriptType + 1]; ScriptData *_currentScript; + Common::HashMap<Common::String, Symbol *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _vars; + inst *_pc; StackData _stack; diff --git a/engines/director/module.mk b/engines/director/module.mk index 2d0bb51646..0d46b09890 100644 --- a/engines/director/module.mk +++ b/engines/director/module.mk @@ -8,9 +8,9 @@ MODULE_OBJS = \ resource.o \ score.o \ sound.o \ + lingo/lingo-gr.o \ lingo/lingo.o \ lingo/lingo-funcs.o \ - lingo/lingo-gr.o \ lingo/lingo-lex.o engines/director/lingo/lingo-lex.cpp: engines/director/lingo/lingo-lex.l |