diff --git a/porth.py b/porth.py index 212dfbcc..01b02049 100755 --- a/porth.py +++ b/porth.py @@ -65,6 +65,7 @@ class Intrinsic(Enum): FORTH_LOAD64=auto() FORTH_STORE64=auto() CAST_PTR=auto() + CAST_INT=auto() ARGC=auto() ARGV=auto() HERE=auto() @@ -201,7 +202,7 @@ def simulate_little_endian_linux(program: Program, argv: List[str]): else: ip += 1 elif op.typ == OpType.INTRINSIC: - assert len(Intrinsic) == 41, "Exhaustive handling of intrinsic in simulate_little_endian_linux()" + assert len(Intrinsic) == 42, "Exhaustive handling of intrinsic in simulate_little_endian_linux()" if op.operand == Intrinsic.PLUS: a = stack.pop() b = stack.pop() @@ -385,6 +386,9 @@ def simulate_little_endian_linux(program: Program, argv: List[str]): elif op.operand == Intrinsic.CAST_PTR: # Ignore the type casting. It's only useful for type_check_program() phase ip += 1 + elif op.operand == Intrinsic.CAST_INT: + # Ignore the type casting. It's only useful for type_check_program() phase + ip += 1 elif op.operand == Intrinsic.SYSCALL0: syscall_number = stack.pop(); if syscall_number == 39: # SYS_getpid @@ -538,7 +542,7 @@ def type_check_program(program: Program): stack.append((DataType.INT, op.token)) stack.append((DataType.PTR, op.token)) elif op.typ == OpType.INTRINSIC: - assert len(Intrinsic) == 41, "Exhaustive intrinsic handling in type_check_program()" + assert len(Intrinsic) == 42, "Exhaustive intrinsic handling in type_check_program()" assert isinstance(op.operand, Intrinsic), "This could be a bug in compilation step" if op.operand == Intrinsic.PLUS: assert len(DataType) == 3, "Exhaustive type handling in PLUS intrinsic" @@ -914,6 +918,14 @@ def type_check_program(program: Program): a_type, a_token = stack.pop() stack.append((DataType.PTR, a_token)) + elif op.operand == Intrinsic.CAST_INT: + if len(stack) < 1: + not_enough_arguments(op) + exit(1) + + a_type, a_token = stack.pop() + + stack.append((DataType.INT, a_token)) elif op.operand == Intrinsic.ARGC: stack.append((DataType.INT, op.token)) elif op.operand == Intrinsic.ARGV: @@ -1122,7 +1134,7 @@ def generate_nasm_linux_x86_64(program: Program, out_file_path: str): assert isinstance(op.operand, int), "This could be a bug in the compilation step" out.write(" jz addr_%d\n" % op.operand) elif op.typ == OpType.INTRINSIC: - assert len(Intrinsic) == 41, "Exhaustive intrinsic handling in generate_nasm_linux_x86_64()" + assert len(Intrinsic) == 42, "Exhaustive intrinsic handling in generate_nasm_linux_x86_64()" if op.operand == Intrinsic.PLUS: out.write(" ;; -- plus --\n") out.write(" pop rax\n") @@ -1332,6 +1344,8 @@ def generate_nasm_linux_x86_64(program: Program, out_file_path: str): out.write(" mov [rax], rbx\n"); elif op.operand == Intrinsic.CAST_PTR: out.write(" ;; -- cast(ptr) --\n") + elif op.operand == Intrinsic.CAST_INT: + out.write(" ;; -- cast(int) --\n") elif op.operand == Intrinsic.SYSCALL0: out.write(" ;; -- syscall0 --\n") out.write(" pop rax\n") @@ -1415,7 +1429,7 @@ def generate_nasm_linux_x86_64(program: Program, out_file_path: str): 'include': Keyword.INCLUDE, } -assert len(Intrinsic) == 41, "Exhaustive INTRINSIC_BY_NAMES definition" +assert len(Intrinsic) == 42, "Exhaustive INTRINSIC_BY_NAMES definition" INTRINSIC_BY_NAMES = { '+': Intrinsic.PLUS, '-': Intrinsic.MINUS, @@ -1448,6 +1462,7 @@ def generate_nasm_linux_x86_64(program: Program, out_file_path: str): '!64': Intrinsic.FORTH_STORE64, '@64': Intrinsic.FORTH_LOAD64, 'cast(ptr)': Intrinsic.CAST_PTR, + 'cast(int)': Intrinsic.CAST_INT, 'argc': Intrinsic.ARGC, 'argv': Intrinsic.ARGV, 'here': Intrinsic.HERE, diff --git a/tests/.gitignore b/tests/.gitignore index 489e969f..1f8d2f29 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,5 +1,6 @@ arithmetics bitwise +cast-int comparison memory stack diff --git a/tests/cast-int.porth b/tests/cast-int.porth new file mode 100644 index 00000000..8633dcb9 --- /dev/null +++ b/tests/cast-int.porth @@ -0,0 +1 @@ +10 cast(ptr) cast(int) 4 5 < cast(int) + print diff --git a/tests/cast-int.txt b/tests/cast-int.txt new file mode 100644 index 00000000..698ae008 --- /dev/null +++ b/tests/cast-int.txt @@ -0,0 +1,9 @@ +:i argc 0 +:b stdin 0 + +:i returncode 0 +:b stdout 3 +11 + +:b stderr 0 +