Skip to content

Commit 8c0f554

Browse files
committed
Make all of the test cases type check
1 parent 1b01538 commit 8c0f554

File tree

6 files changed

+39
-33
lines changed

6 files changed

+39
-33
lines changed

porth.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class Intrinsic(Enum):
5252
STORE=auto()
5353
LOAD64=auto()
5454
STORE64=auto()
55+
CAST_PTR=auto()
5556
ARGC=auto()
5657
ARGV=auto()
5758
SYSCALL0=auto()
@@ -184,7 +185,7 @@ def simulate_little_endian_linux(program: Program, argv: List[str]):
184185
else:
185186
ip += 1
186187
elif op.typ == OpType.INTRINSIC:
187-
assert len(Intrinsic) == 33, "Exhaustive handling of intrinsic in simulate_little_endian_linux()"
188+
assert len(Intrinsic) == 34, "Exhaustive handling of intrinsic in simulate_little_endian_linux()"
188189
if op.operand == Intrinsic.PLUS:
189190
a = stack.pop()
190191
b = stack.pop()
@@ -315,6 +316,9 @@ def simulate_little_endian_linux(program: Program, argv: List[str]):
315316
elif op.operand == Intrinsic.ARGV:
316317
stack.append(argv_buf_ptr)
317318
ip += 1
319+
elif op.operand == Intrinsic.CAST_PTR:
320+
# Ignore the type casting. It's only useful for type_check_program() phase
321+
ip += 1
318322
elif op.operand == Intrinsic.SYSCALL0:
319323
syscall_number = stack.pop();
320324
if syscall_number == 39: # SYS_getpid
@@ -421,7 +425,7 @@ def type_check_program(program: Program):
421425
stack.append((DataType.INT, op.token))
422426
stack.append((DataType.PTR, op.token))
423427
elif op.typ == OpType.INTRINSIC:
424-
assert len(Intrinsic) == 33, "Exhaustive intrinsic handling in type_check_program()"
428+
assert len(Intrinsic) == 34, "Exhaustive intrinsic handling in type_check_program()"
425429
assert isinstance(op.operand, Intrinsic), "This could be a bug in compilation step"
426430
if op.operand == Intrinsic.PLUS:
427431
assert len(DataType) == 3, "Exhaustive type handling in PLUS intrinsic"
@@ -665,7 +669,7 @@ def type_check_program(program: Program):
665669
if a_type == DataType.PTR:
666670
stack.append((DataType.INT, op.token))
667671
else:
668-
compiler_error_(op.token, "invalid argument type for LOAD intrinsic")
672+
compiler_error_(op.token, "invalid argument type for LOAD intrinsic: %s" % a_type)
669673
exit(1)
670674
elif op.operand == Intrinsic.STORE:
671675
assert len(DataType) == 3, "Exhaustive type handling in STORE intrinsic"
@@ -707,6 +711,14 @@ def type_check_program(program: Program):
707711
else:
708712
compiler_error_(op.token, "invalid argument type for STORE64 intrinsic")
709713
exit(1)
714+
elif op.operand == Intrinsic.CAST_PTR:
715+
if len(stack) < 1:
716+
not_enough_arguments(op)
717+
exit(1)
718+
719+
a_type, a_token = stack.pop()
720+
721+
stack.append((DataType.PTR, a_token))
710722
elif op.operand == Intrinsic.ARGC:
711723
stack.append((DataType.INT, op.token))
712724
elif op.operand == Intrinsic.ARGV:
@@ -826,7 +838,7 @@ def type_check_program(program: Program):
826838
else:
827839
assert False, "unreachable"
828840
if len(stack) != 0:
829-
compiler_error_(stack.pop()[1], "unhandled data on the stack")
841+
compiler_error_(stack[-1][1], "unhandled data on the stack: %s" % list(map(lambda x: x[0], stack)))
830842
exit(1)
831843

832844
def generate_nasm_linux_x86_64(program: Program, out_file_path: str):
@@ -912,7 +924,7 @@ def generate_nasm_linux_x86_64(program: Program, out_file_path: str):
912924
assert isinstance(op.operand, int), "This could be a bug in the compilation step"
913925
out.write(" jz addr_%d\n" % op.operand)
914926
elif op.typ == OpType.INTRINSIC:
915-
assert len(Intrinsic) == 33, "Exhaustive intrinsic handling in generate_nasm_linux_x86_64()"
927+
assert len(Intrinsic) == 34, "Exhaustive intrinsic handling in generate_nasm_linux_x86_64()"
916928
if op.operand == Intrinsic.PLUS:
917929
out.write(" ;; -- plus --\n")
918930
out.write(" pop rax\n")
@@ -1077,6 +1089,8 @@ def generate_nasm_linux_x86_64(program: Program, out_file_path: str):
10771089
out.write(" pop rbx\n");
10781090
out.write(" pop rax\n");
10791091
out.write(" mov [rax], rbx\n");
1092+
elif op.operand == Intrinsic.CAST_PTR:
1093+
out.write(" ;; -- cast(ptr) --\n")
10801094
elif op.operand == Intrinsic.SYSCALL0:
10811095
out.write(" ;; -- syscall0 --\n")
10821096
out.write(" pop rax\n")
@@ -1160,7 +1174,7 @@ def generate_nasm_linux_x86_64(program: Program, out_file_path: str):
11601174
'include': Keyword.INCLUDE,
11611175
}
11621176

1163-
assert len(Intrinsic) == 33, "Exhaustive INTRINSIC_BY_NAMES definition"
1177+
assert len(Intrinsic) == 34, "Exhaustive INTRINSIC_BY_NAMES definition"
11641178
INTRINSIC_BY_NAMES = {
11651179
'+': Intrinsic.PLUS,
11661180
'-': Intrinsic.MINUS,
@@ -1186,6 +1200,7 @@ def generate_nasm_linux_x86_64(program: Program, out_file_path: str):
11861200
',': Intrinsic.LOAD,
11871201
'.64': Intrinsic.STORE64,
11881202
',64': Intrinsic.LOAD64,
1203+
'cast(ptr)': Intrinsic.CAST_PTR,
11891204
'argc': Intrinsic.ARGC,
11901205
'argv': Intrinsic.ARGV,
11911206
'syscall0': Intrinsic.SYSCALL0,
@@ -1470,7 +1485,6 @@ def usage(compiler_name: str):
14701485
print(" -debug Enable debug mode.")
14711486
print(" -I <path> Add the path to the include search list")
14721487
print(" -E <expansion-limit> Macro and include expansion limit. (Default %d)" % DEFAULT_EXPANSION_LIMIT)
1473-
print(" -check Type check the program")
14741488
print(" SUBCOMMAND:")
14751489
print(" sim <file> Simulate the program")
14761490
print(" com [OPTIONS] <file> Compile the program")
@@ -1487,7 +1501,6 @@ def usage(compiler_name: str):
14871501

14881502
include_paths = ['.', './std/']
14891503
expansion_limit = DEFAULT_EXPANSION_LIMIT
1490-
check = False
14911504

14921505
while len(argv) > 0:
14931506
if argv[0] == '-debug':
@@ -1509,9 +1522,6 @@ def usage(compiler_name: str):
15091522
exit(1)
15101523
arg, *argv = argv
15111524
expansion_limit = int(arg)
1512-
elif argv[0] == '-check':
1513-
argv = argv[1:]
1514-
check = True
15151525
else:
15161526
break
15171527

@@ -1534,8 +1544,7 @@ def usage(compiler_name: str):
15341544
program_path, *argv = argv
15351545
include_paths.append(path.dirname(program_path))
15361546
program = compile_file_to_program(program_path, include_paths, expansion_limit);
1537-
if check:
1538-
type_check_program(program)
1547+
type_check_program(program)
15391548
simulate_little_endian_linux(program, [program_path] + argv)
15401549
elif subcommand == "com":
15411550
silent = False
@@ -1591,8 +1600,7 @@ def usage(compiler_name: str):
15911600
include_paths.append(path.dirname(program_path))
15921601

15931602
program = compile_file_to_program(program_path, include_paths, expansion_limit);
1594-
if check:
1595-
type_check_program(program)
1603+
type_check_program(program)
15961604
generate_nasm_linux_x86_64(program, basepath + ".asm")
15971605
cmd_call_echoed(["nasm", "-felf64", basepath + ".asm"], silent)
15981606
cmd_call_echoed(["ld", "-o", basepath, basepath + ".o"], silent)

test.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,12 @@ def run_test_for_file(file_path: str) -> Tuple[bool, bool]:
9191
print("[ERROR] Unexpected simulation output")
9292
print(" Expected:")
9393
print(" return code: %s" % tc.returncode)
94-
print(" stdout: %s" % tc.stdout.decode("utf-8"))
95-
print(" stderr: %s" % tc.stderr.decode("utf-8"))
94+
print(" stdout: \n%s" % tc.stdout.decode("utf-8"))
95+
print(" stderr: \n%s" % tc.stderr.decode("utf-8"))
9696
print(" Actual:")
9797
print(" return code: %s" % sim.returncode)
98-
print(" stdout: %s" % sim.stdout.decode("utf-8"))
99-
print(" stderr: %s" % sim.stderr.decode("utf-8"))
98+
print(" stdout: \n%s" % sim.stdout.decode("utf-8"))
99+
print(" stderr: \n%s" % sim.stderr.decode("utf-8"))
100100

101101
com = cmd_run_echoed([sys.executable, "./porth.py", "com", "-r", "-s", file_path, *tc.argv], input=tc.stdin, capture_output=True)
102102
com_ok = True
@@ -105,12 +105,12 @@ def run_test_for_file(file_path: str) -> Tuple[bool, bool]:
105105
print("[ERROR] Unexpected compilation output")
106106
print(" Expected:")
107107
print(" return code: %s" % tc.returncode)
108-
print(" stdout: %s" % tc.stdout.decode("utf-8"))
109-
print(" stderr: %s" % tc.stderr.decode("utf-8"))
108+
print(" stdout: \n%s" % tc.stdout.decode("utf-8"))
109+
print(" stderr: \n%s" % tc.stderr.decode("utf-8"))
110110
print(" Actual:")
111111
print(" return code: %s" % com.returncode)
112-
print(" stdout: %s" % com.stdout.decode("utf-8"))
113-
print(" stderr: %s" % com.stderr.decode("utf-8"))
112+
print(" stdout: \n%s" % com.stdout.decode("utf-8"))
113+
print(" stderr: \n%s" % com.stderr.decode("utf-8"))
114114

115115
return (sim_ok, com_ok)
116116

tests/argv.porth

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ include "./std.porth"
33
argv 8 +
44
argc 1 -
55
while dup 0 > do
6-
over ,64 dup strlen swap
6+
over ,64 dup cast(ptr) strlen swap
77
stdout write drop
88
"\n" stdout write drop
99
1 - swap 8 + swap
1010
end
11+
drop
12+
drop

tests/comments.porth

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ include "std.porth"
66
//////nonsense comment
77

88
// string literal with `//` should be printed
9-
"Hello, // World\n" stdout write // this comment should be allowed
9+
"Hello, // World\n" stdout write drop // this comment should be allowed

tests/dead-recursive-macro.porth

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ macro dead-recursive-macro
44
dead-recursive-macro
55
end
66

7-
"Dead recursive macros should not cause any problems. Because they are never expanded\n" stdout write
7+
"Dead recursive macros should not cause any problems. Because they are never expanded\n" stdout write drop

tests/macros.porth

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
include "std.porth"
22

33
macro check_less
4-
< if
5-
"YES\n" stdout write
6-
else
7-
"NO\n" stdout write
8-
end
4+
< if "YES\n" else "NO\n" end stdout write drop
95
end
106

117
1 2 check_less
@@ -17,9 +13,9 @@ macro even_fibs
1713
over print
1814
end
1915
swap over +
20-
end
16+
end drop drop
2117
end
2218

23-
"------------------------------\n" stdout write
19+
"------------------------------\n" stdout write drop
2420

2521
even_fibs

0 commit comments

Comments
 (0)