aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2016-06-19 18:52:07 +0200
committerEugene Sandulenko2016-08-03 23:40:36 +0200
commit81b056ffc1670dba3e46c42eb5d16263ab724f6e (patch)
tree1e4786034be01e13a07562c1370dc6723dc281c1
parent4a536c57f1012c0bb4380d84ddc2ee72c3f3d332 (diff)
downloadscummvm-rg350-81b056ffc1670dba3e46c42eb5d16263ab724f6e.tar.gz
scummvm-rg350-81b056ffc1670dba3e46c42eb5d16263ab724f6e.tar.bz2
scummvm-rg350-81b056ffc1670dba3e46c42eb5d16263ab724f6e.zip
DIRECTOR: Lingo: Add missing funcs
-rw-r--r--engines/director/director.cpp7
-rw-r--r--engines/director/lingo/lingo-funcs.cpp73
-rw-r--r--engines/director/lingo/lingo-gr.cpp176
-rw-r--r--engines/director/lingo/lingo-gr.h46
-rw-r--r--engines/director/lingo/lingo-gr.y4
-rw-r--r--engines/director/lingo/lingo-lex.cpp36
-rw-r--r--engines/director/lingo/lingo-lex.l3
-rw-r--r--engines/director/lingo/lingo.cpp10
-rw-r--r--engines/director/lingo/lingo.h11
-rw-r--r--engines/director/module.mk2
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