Skip to content

Commit

Permalink
[mycpp] examples/parse.py translates and compiles!
Browse files Browse the repository at this point in the history
Now we just need to print the AST.
  • Loading branch information
Andy Chu committed Apr 9, 2019
1 parent 36a5cdd commit 2c331c3
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 22 deletions.
24 changes: 13 additions & 11 deletions mycpp/examples/parse.py
Expand Up @@ -5,7 +5,7 @@
from __future__ import print_function

import os
from typing import Tuple
from typing import Tuple, Optional
from runtime import log
from _gen.expr_asdl import (
expr_t, expr__Var, expr__Const, expr__Binary, tok_e, tok_t
Expand Down Expand Up @@ -80,7 +80,8 @@ def Next(self):
def Eat(self, tok_val):
# type: (str) -> None
if self.tok_val != tok_val:
raise ParseError('Expected %r, got %r' % (tok_val, self.tok_val))
#raise ParseError('Expected %r, got %r' % (tok_val, self.tok_val))
raise ParseError('Expected ' + tok_val)
self.Next()

def ParseFactor(self):
Expand All @@ -103,7 +104,8 @@ def ParseFactor(self):
self.Eat(')')
return n3

raise ParseError('Unexpected token %s %s' % (self.tok_type, self.tok_val))
#raise ParseError('Unexpected token %s %s' % (self.tok_type, self.tok_val))
raise ParseError('Unexpected token ' + self.tok_val)

def ParseTerm(self):
# type: () -> expr_t
Expand Down Expand Up @@ -145,7 +147,8 @@ def run_tests():
tok_type, tok_val = lex.Read()
if tok_type == tok_e.Eof:
break
print('%s %s' % (tok_type, tok_val))
#print('%s %s' % (tok_type, tok_val))
log('tok_val %s', tok_val)

CASES = [
'1+2', '1+2*3', '1*2+3', '(1+2)*3', 'a+b+c+d', 'a*b*3*4',
Expand All @@ -154,6 +157,8 @@ def run_tests():
'(',
')',
'(a+b',
' ',
' $$ ',
]
for expr in CASES:
lex = Lexer(expr)
Expand All @@ -162,7 +167,7 @@ def run_tests():
log('--')
log('%s =>', expr)

tree = None # type: expr_t
tree = None # type: Optional[expr_t]
try:
tree = p.Parse()
except ParseError as e:
Expand All @@ -179,12 +184,9 @@ def run_benchmarks():
result = 0
i = 0
while i < n:
lex = Lexer('abc')
while True:
tok_type, tok_val = lex.Read()
if tok_type == tok_e.Eof:
break
result += len(tok_val)
lex = Lexer('a*b*3*4')
p = Parser(lex)
tree = p.Parse()

i += 1

Expand Down
21 changes: 19 additions & 2 deletions mycpp/run.sh
Expand Up @@ -330,12 +330,29 @@ benchmark-cartesian() { benchmark cartesian; }
# no timings
benchmark-length() { benchmark length; }

benchmark-parse() { benchmark parse; }

benchmark-containers() { benchmark containers; }

benchmark-control_flow() { benchmark control_flow; }

# Good news! Parsing is 10x faster.
# 198 ms in C++ vs 1,974 in Python! Is that because of the method calls?
benchmark-parse() {
export BENCHMARK=1

local name=parse

echo
echo $'\t[ C++ ]'
time _bin/$name

# TODO: Consolidate this with the above.
# We need 'asdl'
export PYTHONPATH="$REPO_ROOT/mycpp:$REPO_ROOT"
echo
echo $'\t[ Python ]'
time examples/${name}.py
}


build-all() {
for name in "${EXAMPLES[@]}"; do
Expand Down
3 changes: 2 additions & 1 deletion mycpp/runtime.h
Expand Up @@ -90,7 +90,7 @@ class Str {
return false; // special case
}
for (int i = 0; i < len_; ++i) {
if (! ::isalpha(!data_[i])) {
if (! ::isalpha(data_[i])) {
return false;
}
}
Expand Down Expand Up @@ -281,6 +281,7 @@ inline bool maybe_str_equals(Str* left, Str* right) {
//inline int len(Dict* D) {
//}

bool _str_to_int(Str* s, int* result); // for testing only
int str_to_int(Str* s);

#endif // RUNTIME_H
21 changes: 13 additions & 8 deletions mycpp/runtime_test.cc
Expand Up @@ -8,44 +8,48 @@ void test_str_to_int() {
int i;
bool ok;

ok = str_to_int(new Str("345"), &i);
ok = _str_to_int(new Str("345"), &i);
assert(ok);
assert(i == 345);

// TODO: Is there a way to check for overflow?
// strtol returns 'long int'.
ok = str_to_int(new Str("1234567890"), &i);
ok = _str_to_int(new Str("1234567890"), &i);
assert(ok);
log("i = %d", i);
assert(i == 1234567890);

// negative
ok = str_to_int(new Str("-123"), &i);
ok = _str_to_int(new Str("-123"), &i);
assert(ok);
assert(i == -123);

// Leading space is OK!
ok = str_to_int(new Str(" -123"), &i);
ok = _str_to_int(new Str(" -123"), &i);
assert(ok);
assert(i == -123);

// Trailing space is OK! NOTE: This fails!
ok = str_to_int(new Str(" -123 "), &i);
ok = _str_to_int(new Str(" -123 "), &i);
assert(ok);
assert(i == -123);

// Empty string isn't an integer
ok = str_to_int(new Str(""), &i);
ok = _str_to_int(new Str(""), &i);
assert(!ok);

ok = str_to_int(new Str("xx"), &i);
ok = _str_to_int(new Str("xx"), &i);
assert(!ok);

// Trailing garbage
ok = str_to_int(new Str("42a"), &i);
ok = _str_to_int(new Str("42a"), &i);
assert(!ok);
}

void test_str_methods() {
assert((new Str("abc"))->isalpha());
}

int main(int argc, char **argv) {
List<int>* L = new List<int> {1, 2, 3};

Expand Down Expand Up @@ -82,4 +86,5 @@ int main(int argc, char **argv) {
log("t4[3] = %d", t4->at3());

test_str_to_int();
test_str_methods();
}

0 comments on commit 2c331c3

Please sign in to comment.