Skip to content

Commit b7723a9

Browse files
committed
Remove old property access code. Add basic testing infrastructure. Reverse ast generation.
1 parent 572d85f commit b7723a9

File tree

5 files changed

+97
-53
lines changed

5 files changed

+97
-53
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
vbmonkey

run_tests.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env python
2+
import sys
3+
import os.path
4+
import glob
5+
import subprocess
6+
from optparse import OptionParser
7+
8+
def main(argc, argv):
9+
parser = OptionParser()
10+
parser.add_option('-e', '--expand', dest="expandFailures",
11+
action="store_true",
12+
help="show expected/received output from failed tests")
13+
(options, args) = parser.parse_args()
14+
15+
if args:
16+
filenames = args
17+
options.expandFailures = True
18+
else:
19+
filenames = glob.iglob("tests/*.vbs")
20+
21+
failures = 0
22+
for filename in filenames:
23+
base, _ = os.path.splitext(filename)
24+
testInput = open(filename, 'rb')
25+
p = subprocess.Popen("./vbmonkey --no-prompt",
26+
stdin=testInput,
27+
stdout=subprocess.PIPE,
28+
stderr=subprocess.STDOUT,
29+
shell=True)
30+
output = p.communicate()[0].strip()
31+
expectedFilename = base + '.expected'
32+
try:
33+
expected = open(expectedFilename, 'rb')
34+
except IOError:
35+
print "MISSING:", expectedFilename
36+
continue
37+
expectedOutput = expected.read().strip()
38+
if output != expectedOutput:
39+
print "FAILED:", filename
40+
if options.expandFailures:
41+
print "---- got\n{0}\n---- expected\n{1}\n". \
42+
format(output, expectedOutput)
43+
failures += 1
44+
expected.close()
45+
testInput.close()
46+
return failures != 0
47+
48+
if __name__ == "__main__":
49+
sys.exit(main(len(sys.argv), sys.argv))

tests/basic_ops.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
IDENTIFIER (a) OP IDENTIFIER (b)
2+
IDENTIFIER (a) OP IDENTIFIER (b)
3+
IDENTIFIER (a) OP IDENTIFIER (b)
4+
IDENTIFIER (a) OP IDENTIFIER (b)
5+
IDENTIFIER (a) OP IDENTIFIER (b) OP IDENTIFIER (c)

tests/basic_ops.vbs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
a + b
2+
a - b
3+
a * b
4+
a / b
5+
a + b + c

vbmonkey.cpp

Lines changed: 37 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ struct Token
2727
COMMA,
2828
LPAREN,
2929
RPAREN,
30-
PROPERTY_ACCESS,
3130
EQUALS,
3231
EOL
3332
} type;
@@ -224,21 +223,6 @@ namespace ast
224223
std::string name_;
225224
};
226225

227-
class PropertyAccess : public Expr
228-
{
229-
public:
230-
PropertyAccess(Expr *owner, Expr *property)
231-
: owner_(owner), property_(property) {}
232-
std::string toString()
233-
{
234-
return owner_->toString() + " " + property_->toString();
235-
}
236-
237-
private:
238-
Expr *owner_;
239-
Expr *property_;
240-
};
241-
242226
class Dim : public Node
243227
{
244228
public:
@@ -393,45 +377,33 @@ ast::Expr *parseIdentifier(TokenIt &it, const TokenIt &end)
393377

394378
std::string identifier = current->value;
395379
current = nextToken(it, end);
396-
if(!current || (current->type != Token::LPAREN &&
397-
current->type != Token::PROPERTY_ACCESS))
380+
if(!current || current->type != Token::LPAREN)
398381
return new ast::Identifier(identifier);
399382

400-
if(current->type == Token::LPAREN)
401-
{
402-
current = nextToken(it, end);
403-
EXPECT_ANY_TOKEN(current, errorE, "Expression or ')' expected");
383+
current = nextToken(it, end);
384+
EXPECT_ANY_TOKEN(current, errorE, "Expression or ')' expected");
404385

405-
std::vector<ast::Expr *> args;
406-
if(current->type != Token::RPAREN)
407-
while(1)
408-
{
409-
ast::Expr *arg = parseExpr(it, end);
410-
if(!arg) return NULL;
411-
args.push_back(arg);
412-
413-
current = currentToken(it, end);
414-
EXPECT_ANY_TOKEN(current, errorE, "Expected ')' or ','");
415-
416-
if(current->type == Token::RPAREN)
417-
break;
418-
else if(current->type != Token::COMMA)
419-
return errorE("Expected ')' or ','");
386+
std::vector<ast::Expr *> args;
387+
if(current->type != Token::RPAREN)
388+
while(1)
389+
{
390+
ast::Expr *arg = parseExpr(it, end);
391+
if(!arg) return NULL;
392+
args.push_back(arg);
420393

421-
current = nextToken(it, end);
422-
}
394+
current = currentToken(it, end);
395+
EXPECT_ANY_TOKEN(current, errorE, "Expected ')' or ','");
423396

424-
nextToken(it, end);
425-
return new ast::CallExpr(identifier, args);
426-
}
397+
if(current->type == Token::RPAREN)
398+
break;
399+
else if(current->type != Token::COMMA)
400+
return errorE("Expected ')' or ','");
427401

428-
current = nextToken(it, end);
429-
EXPECT_TOKEN_E(current, Token::IDENTIFIER, "Identifier expected after '.'");
402+
current = nextToken(it, end);
403+
}
430404

431-
ast::Expr *property = parseIdentifier(it, end);
432-
//if(!property)
433-
return errorE("Identifier expected after '.'");
434-
//return new ast::PropertyAccess(identifier, property);
405+
nextToken(it, end);
406+
return new ast::CallExpr(identifier, args);
435407
}
436408

437409
ast::Expr *parsePrimary(TokenIt &it, const TokenIt &end)
@@ -589,20 +561,32 @@ ASTNodeList *generateAST(const TokenList &tokens)
589561
{
590562
node = parseTopLevel(it, end);
591563
if(node)
592-
ast->push_back(node);
564+
ast->push_front(node);
593565
else break;
594566
}
595567
return ast;
596568
}
597569

598-
int main(int /*argc*/, char */*argv*/[])
570+
int main(int argc, char *argv[])
599571
{
600-
std::list<Token *> tokens;
572+
bool showPrompt = true;
573+
for(int i = 1; i < argc; i++)
574+
{
575+
if(!std::strcmp(argv[i], "--no-prompt"))
576+
{
577+
showPrompt = false;
578+
continue;
579+
}
580+
581+
std::cout << "unhandled: " << argv[i] << std::endl;
582+
}
583+
584+
TokenList tokens;
601585

602586
do
603587
{
604588
tokens.clear();
605-
std::cout << "> ";
589+
if(showPrompt) std::cout << "> ";
606590

607591
while(1)
608592
{
@@ -622,6 +606,6 @@ int main(int /*argc*/, char */*argv*/[])
622606
std::cin.clear();
623607
} while(tokens.size());
624608

625-
std::cout << std::endl;
609+
if(showPrompt) std::cout << std::endl;
626610
return 0;
627611
}

0 commit comments

Comments
 (0)