@@ -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
832844def 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"
11641178INTRINSIC_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 )
0 commit comments