diff --git a/lib/pinc_bytecode/bytecode.ml b/lib/pinc_bytecode/bytecode.ml index b91291a..461955a 100644 --- a/lib/pinc_bytecode/bytecode.ml +++ b/lib/pinc_bytecode/bytecode.ml @@ -1,6 +1,6 @@ type t = { instructions : Bytes.t; - constants : Value.t UInt16.Map.t; + constants : Value.t Int32.Map.t; } let make ~instructions ~constants = { instructions; constants } diff --git a/lib/pinc_bytecode/instruction.ml b/lib/pinc_bytecode/instruction.ml index 34cacea..74de0a5 100644 --- a/lib/pinc_bytecode/instruction.ml +++ b/lib/pinc_bytecode/instruction.ml @@ -1,7 +1,7 @@ type t = | I_Null | I_Pop - | I_Constant of UInt16.t + | I_Constant of Int32.t | I_Add | I_Sub | I_Div @@ -20,10 +20,10 @@ type t = | I_Or | I_Minus | I_Not - | I_Jump of UInt16.t - | I_Jump_If_False of UInt16.t - | I_Set_Global of UInt16.t - | I_Get_Global of UInt16.t + | I_Jump of Int32.t + | I_Jump_If_False of Int32.t + | I_Set_Global of Int32.t + | I_Get_Global of Int32.t let byte = function | I_Pop -> 0x00 @@ -55,7 +55,7 @@ let byte = function let operands_length = function | I_Constant op | I_Jump op | I_Jump_If_False op | I_Set_Global op | I_Get_Global op -> - UInt16.width op + Int32.byte_width op | I_Pop | I_Add | I_Sub @@ -84,7 +84,7 @@ let decode bytes offset = match instruction with | 0x00 -> (offset, I_Pop) | 0x01 -> - let offset, addr = UInt16.read bytes offset in + let offset, addr = Int32.read_bytes bytes offset in (offset, I_Constant addr) | 0x02 -> (offset, I_Add) | 0x03 -> (offset, I_Sub) @@ -105,17 +105,17 @@ let decode bytes offset = | 0x12 -> (offset, I_Minus) | 0x13 -> (offset, I_Not) | 0x14 -> - let offset, addr = UInt16.read bytes offset in + let offset, addr = Int32.read_bytes bytes offset in (offset, I_Jump addr) | 0x15 -> - let offset, addr = UInt16.read bytes offset in + let offset, addr = Int32.read_bytes bytes offset in (offset, I_Jump_If_False addr) | 0x16 -> (offset, I_Null) | 0x17 -> - let offset, addr = UInt16.read bytes offset in + let offset, addr = Int32.read_bytes bytes offset in (offset, I_Set_Global addr) | 0x18 -> - let offset, addr = UInt16.read bytes offset in + let offset, addr = Int32.read_bytes bytes offset in (offset, I_Get_Global addr) | _ -> raise_notrace @@ -124,7 +124,7 @@ let decode bytes offset = let pp fmt = function | I_Pop -> Format.fprintf fmt "I_Pop" - | I_Constant addr -> Format.fprintf fmt "I_Constant %a" UInt16.pp addr + | I_Constant addr -> Format.fprintf fmt "I_Constant %a" Int32.pp addr | I_Add -> Format.fprintf fmt "I_Add" | I_Sub -> Format.fprintf fmt "I_Sub" | I_Div -> Format.fprintf fmt "I_Div" @@ -143,11 +143,11 @@ let pp fmt = function | I_Or -> Format.fprintf fmt "I_Or" | I_Minus -> Format.fprintf fmt "I_Minus" | I_Not -> Format.fprintf fmt "I_Not" - | I_Jump addr -> Format.fprintf fmt "I_Jump %a" UInt16.pp addr - | I_Jump_If_False addr -> Format.fprintf fmt "I_Jump_If_False %a" UInt16.pp addr + | I_Jump addr -> Format.fprintf fmt "I_Jump %a" Int32.pp addr + | I_Jump_If_False addr -> Format.fprintf fmt "I_Jump_If_False %a" Int32.pp addr | I_Null -> Format.fprintf fmt "I_Null" - | I_Get_Global addr -> Format.fprintf fmt "I_Get_Global %a" UInt16.pp addr - | I_Set_Global addr -> Format.fprintf fmt "I_Set_Global %a" UInt16.pp addr + | I_Get_Global addr -> Format.fprintf fmt "I_Get_Global %a" Int32.pp addr + | I_Set_Global addr -> Format.fprintf fmt "I_Set_Global %a" Int32.pp addr ;; let to_bytes t = @@ -163,7 +163,7 @@ let to_bytes t = let () = match t with | I_Constant op | I_Jump op | I_Jump_If_False op | I_Set_Global op | I_Get_Global op - -> offset := UInt16.write bytes !offset op + -> offset := Int32.write_bytes bytes !offset op | I_Pop | I_Add | I_Sub diff --git a/lib/pinc_compiler/compiler.ml b/lib/pinc_compiler/compiler.ml index f12bf27..dbe9c02 100644 --- a/lib/pinc_compiler/compiler.ml +++ b/lib/pinc_compiler/compiler.ml @@ -7,7 +7,7 @@ type emitted_instruction = { type t = { instructions : Buffer.t; - constants : Pinc_Bytecode.Value.t UInt16.Map.t; + constants : Pinc_Bytecode.Value.t Int32.Map.t; mutable last_instruction : emitted_instruction; mutable previous_instruction : emitted_instruction; symbol_table : SymbolTable.t; @@ -43,14 +43,14 @@ let remove_last_pop t = let add_constant = let id = - let id' = ref (UInt16.make 0) in + let id' = ref Int32.zero in fun () -> - UInt16.incr id'; + id' := Int32.succ !id'; !id' in fun t constant -> let new_id = id () in - let constants = UInt16.Map.add new_id constant t.constants in + let constants = Int32.Map.add new_id constant t.constants in (new_id, { t with constants }) ;; @@ -149,15 +149,15 @@ and compile_conditional_expression t ~condition ~consequent ~alternate = (* Consequent *) (* We create a conditional jump with a temporary address first, because we do not know where we should jump to next. *) - let t = emit t (Pinc_Bytecode.Instruction.I_Jump_If_False (UInt16.make 0xFFFF)) in + let t = emit t (Pinc_Bytecode.Instruction.I_Jump_If_False 0xFFFFFFFl) in let jump_consequent_offset = t.last_instruction.offset in let t = compile_expr t consequent in let t = remove_last_pop t in (* Alternate *) - let t = emit t (Pinc_Bytecode.Instruction.I_Jump (UInt16.make 0xFFFF)) in + let t = emit t (Pinc_Bytecode.Instruction.I_Jump 0xFFFFFFFl) in let jump_alternate_offset = t.last_instruction.offset in - let jump_address = UInt16.make (Buffer.length t.instructions) in + let jump_address = Int32.of_int (Buffer.length t.instructions) in let t = replace_instruction t jump_consequent_offset @@ Pinc_Bytecode.Instruction.I_Jump_If_False jump_address @@ -170,7 +170,7 @@ and compile_conditional_expression t ~condition ~consequent ~alternate = let t = remove_last_pop t in t in - let jump_address = UInt16.make (Buffer.length t.instructions) in + let jump_address = Int32.of_int (Buffer.length t.instructions) in let t = replace_instruction t jump_alternate_offset @@ Pinc_Bytecode.Instruction.I_Jump jump_address @@ -211,7 +211,7 @@ let compile (ast : Pinc_Types.Ast.t) = let t = { instructions = Buffer.create 8; - constants = UInt16.Map.empty; + constants = Int32.Map.empty; previous_instruction = empty_instruction; last_instruction = empty_instruction; symbol_table = SymbolTable.make (); diff --git a/lib/pinc_core/Pinc_Core.ml b/lib/pinc_core/Pinc_Core.ml index d48add5..5a46276 100644 --- a/lib/pinc_core/Pinc_Core.ml +++ b/lib/pinc_core/Pinc_Core.ml @@ -4,7 +4,6 @@ module StringSet = StringSet module SymbolTable = SymbolTable module Identifier = Identifier module Utf8String = Utf8String -module UInt16 = UInt16 module Dedent = struct let indentation = diff --git a/lib/pinc_core/StdlibExtension.ml b/lib/pinc_core/StdlibExtension.ml index 5e25522..8433d1e 100644 --- a/lib/pinc_core/StdlibExtension.ml +++ b/lib/pinc_core/StdlibExtension.ml @@ -195,3 +195,23 @@ module Buffer = struct let pp_bytes t = t |> Buffer.to_bytes |> Bytes.pp_hum end + +module Int32 = struct + include Int32 + + let byte_width (_ : Int32.t) = 4 + + let write_bytes bytes offset t = + Bytes.set_int32_be bytes offset t; + offset + byte_width t + ;; + + let read_bytes bytes offset = + let result = Bytes.get_int32_be bytes offset in + (offset + byte_width result, result) + ;; + + let pp fmt t = Format.fprintf fmt "0x%08lX (%08li)" t t + + module Map = Map.Make (Int32) +end diff --git a/lib/pinc_core/SymbolTable.ml b/lib/pinc_core/SymbolTable.ml index b93c9d7..01c40eb 100644 --- a/lib/pinc_core/SymbolTable.ml +++ b/lib/pinc_core/SymbolTable.ml @@ -1,21 +1,21 @@ type t = { store : symbol StringMap.t; - length : UInt16.t; + length : Int32.t; } and symbol = { name : string; scope : scope; - address : UInt16.t; + address : Int32.t; } and scope = Global -let make () = { store = StringMap.empty; length = UInt16.make 0 } +let make () = { store = StringMap.empty; length = Int32.zero } let define_symbol t ~name = let symbol = { name; scope = Global; address = t.length } in - { store = StringMap.add name symbol t.store; length = UInt16.succ t.length } + { store = StringMap.add name symbol t.store; length = Int32.succ t.length } ;; let resolve_symbol t ~name = StringMap.find_opt name t.store diff --git a/lib/pinc_core/UInt16.ml b/lib/pinc_core/UInt16.ml deleted file mode 100644 index 12c7b29..0000000 --- a/lib/pinc_core/UInt16.ml +++ /dev/null @@ -1,30 +0,0 @@ -module T = struct - include Int - - let make i = - if i > 65535 then - raise (Invalid_argument "UInt16.make") - else - i - ;; - - let to_int t = t - let width _ = 2 - let max_value = 65535 - - let write bytes offset t = - Bytes.set_uint16_be bytes offset t; - offset + width t - ;; - - let read bytes offset = - let result = Bytes.get_uint16_be bytes offset in - (offset + width result, result) - ;; - - let incr = incr - let pp fmt t = Format.fprintf fmt "0x%04X (%04i)" t t -end - -include T -module Map = Map.Make (T) diff --git a/lib/pinc_core/UInt16.mli b/lib/pinc_core/UInt16.mli deleted file mode 100644 index 8277677..0000000 --- a/lib/pinc_core/UInt16.mli +++ /dev/null @@ -1,14 +0,0 @@ -type t - -val make : int -> t -val to_int : t -> int -val width : t -> int -val max_value : int -val write : Bytes.t -> int -> t -> int -val read : Bytes.t -> int -> int * t -val compare : t -> t -> int -val succ : t -> t -val incr : t ref -> unit -val pp : Format.formatter -> t -> unit - -module Map : Map.S with type key := t diff --git a/lib/pinc_vm/vm.ml b/lib/pinc_vm/vm.ml index 093bbb2..4c1c516 100644 --- a/lib/pinc_vm/vm.ml +++ b/lib/pinc_vm/vm.ml @@ -7,7 +7,7 @@ exception TODO type t = { bytecode : Bytecode.t; stack : Value.t Stack.t; - globals : Value.t Array.t; + mutable globals : Value.t Int32.Map.t; } let stack_size = 2048 @@ -16,7 +16,7 @@ let make (bytecode : Bytecode.t) = { bytecode; stack = Stack.make ~size:stack_size ~default_value:Value.Null; - globals = Array.make UInt16.max_value Value.Null; + globals = Int32.Map.empty; } ;; @@ -203,7 +203,7 @@ let run t = match op with | Instruction.I_Pop -> ignore @@ Stack.pop t.stack | Instruction.I_Constant addr -> - let constant = UInt16.Map.find addr t.bytecode.constants in + let constant = Int32.Map.find addr t.bytecode.constants in Stack.push t.stack constant | Instruction.I_Add -> execute_binary_operation t Operators.Binary.PLUS | Instruction.I_Sub -> execute_binary_operation t Operators.Binary.MINUS @@ -224,20 +224,20 @@ let run t = | Instruction.I_Or -> execute_binary_operation t Operators.Binary.OR | Instruction.I_Minus -> execute_unary_operation t Operators.Unary.MINUS | Instruction.I_Not -> execute_unary_operation t Operators.Unary.NOT - | Instruction.I_Jump addr -> ip := UInt16.to_int addr + | Instruction.I_Jump addr -> ip := Int32.to_int addr | Instruction.I_Jump_If_False addr -> let condition = Stack.pop t.stack in let () = if not @@ Value.is_true condition then - ip := UInt16.to_int addr + ip := Int32.to_int addr in () | Instruction.I_Null -> Stack.push t.stack Value.Null | Instruction.I_Set_Global addr -> let value = Stack.pop t.stack in - t.globals.(UInt16.to_int addr) <- value + t.globals <- Int32.Map.add addr value t.globals | Instruction.I_Get_Global addr -> - let value = t.globals.(UInt16.to_int addr) in + let value = Int32.Map.find addr t.globals in Stack.push t.stack value in () diff --git a/test/vm/run.t b/test/vm/run.t index 2d859fa..a0dc732 100644 --- a/test/vm/run.t +++ b/test/vm/run.t @@ -2,93 +2,93 @@ 12 $ NO_COLOR="1" print_instructions . Add - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Add - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Add + 0011 I_Pop $ NO_COLOR="1" print_vm . Sub 2 $ NO_COLOR="1" print_instructions . Sub - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Sub - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Sub + 0011 I_Pop $ NO_COLOR="1" print_vm . Div 1.4 $ NO_COLOR="1" print_instructions . Div - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Div - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Div + 0011 I_Pop $ NO_COLOR="1" print_vm . Mul 35 $ NO_COLOR="1" print_instructions . Mul - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Mul - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Mul + 0011 I_Pop $ NO_COLOR="1" print_vm . Mod 2 $ NO_COLOR="1" print_instructions . Mod - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Mod - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Mod + 0011 I_Pop $ NO_COLOR="1" print_vm . Pow 16807 $ NO_COLOR="1" print_instructions . Pow - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Pow - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Pow + 0011 I_Pop $ NO_COLOR="1" print_vm . MinusInt -5 $ NO_COLOR="1" print_instructions . MinusInt - 0000 I_Constant 0x0001 (0001) - 0003 I_Minus - 0004 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Minus + 0006 I_Pop $ NO_COLOR="1" print_vm . MinusFloat -3.14 $ NO_COLOR="1" print_instructions . MinusFloat - 0000 I_Constant 0x0001 (0001) - 0003 I_Minus - 0004 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Minus + 0006 I_Pop $ NO_COLOR="1" print_vm . Math 5 $ NO_COLOR="1" print_instructions . Math - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Mul - 0007 I_Constant 0x0003 (0003) - 0010 I_Constant 0x0004 (0004) - 0013 I_Constant 0x0005 (0005) - 0016 I_Constant 0x0006 (0006) - 0019 I_Mul - 0020 I_Add - 0021 I_Constant 0x0007 (0007) - 0024 I_Pow - 0025 I_Div - 0026 I_Add - 0027 I_Constant 0x0008 (0008) - 0030 I_Minus - 0031 I_Add - 0032 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Mul + 0011 I_Constant 0x00000003 (00000003) + 0016 I_Constant 0x00000004 (00000004) + 0021 I_Constant 0x00000005 (00000005) + 0026 I_Constant 0x00000006 (00000006) + 0031 I_Mul + 0032 I_Add + 0033 I_Constant 0x00000007 (00000007) + 0038 I_Pow + 0039 I_Div + 0040 I_Add + 0041 I_Constant 0x00000008 (00000008) + 0046 I_Minus + 0047 I_Add + 0048 I_Pop $ NO_COLOR="1" print_vm . True true @@ -126,55 +126,55 @@ false $ NO_COLOR="1" print_instructions . Equal - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Equal - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Equal + 0011 I_Pop $ NO_COLOR="1" print_vm . NotEqual true $ NO_COLOR="1" print_instructions . NotEqual - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Not_Equal - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Not_Equal + 0011 I_Pop $ NO_COLOR="1" print_vm . Greater false $ NO_COLOR="1" print_instructions . Greater - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Greater - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Greater + 0011 I_Pop $ NO_COLOR="1" print_vm . GreaterEqual false $ NO_COLOR="1" print_instructions . GreaterEqual - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Greater_Equal - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Greater_Equal + 0011 I_Pop $ NO_COLOR="1" print_vm . Less true $ NO_COLOR="1" print_instructions . Less - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Less - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Less + 0011 I_Pop $ NO_COLOR="1" print_vm . LessEqual true $ NO_COLOR="1" print_instructions . LessEqual - 0000 I_Constant 0x0001 (0001) - 0003 I_Constant 0x0002 (0002) - 0006 I_Less_Equal - 0007 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Constant 0x00000002 (00000002) + 0010 I_Less_Equal + 0011 I_Pop $ NO_COLOR="1" print_vm . Not false @@ -189,55 +189,55 @@ $ NO_COLOR="1" print_instructions . IfTrue 0000 I_True - 0001 I_Jump_If_False 0x0008 (0008) - 0004 I_True - 0005 I_Jump 0x0009 (0009) - 0008 I_Null - 0009 I_Pop + 0001 I_Jump_If_False 0x0000000C (00000012) + 0006 I_True + 0007 I_Jump 0x0000000D (00000013) + 0012 I_Null + 0013 I_Pop $ NO_COLOR="1" print_vm . IfTrueElse true $ NO_COLOR="1" print_instructions . IfTrueElse 0000 I_True - 0001 I_Jump_If_False 0x0008 (0008) - 0004 I_True - 0005 I_Jump 0x0009 (0009) - 0008 I_False - 0009 I_Pop + 0001 I_Jump_If_False 0x0000000C (00000012) + 0006 I_True + 0007 I_Jump 0x0000000D (00000013) + 0012 I_False + 0013 I_Pop $ NO_COLOR="1" print_vm . IfFalse $ NO_COLOR="1" print_instructions . IfFalse 0000 I_False - 0001 I_Jump_If_False 0x0008 (0008) - 0004 I_True - 0005 I_Jump 0x0009 (0009) - 0008 I_Null - 0009 I_Pop + 0001 I_Jump_If_False 0x0000000C (00000012) + 0006 I_True + 0007 I_Jump 0x0000000D (00000013) + 0012 I_Null + 0013 I_Pop $ NO_COLOR="1" print_vm . IfFalseElse false $ NO_COLOR="1" print_instructions . IfFalseElse 0000 I_False - 0001 I_Jump_If_False 0x0008 (0008) - 0004 I_True - 0005 I_Jump 0x0009 (0009) - 0008 I_False - 0009 I_Pop + 0001 I_Jump_If_False 0x0000000C (00000012) + 0006 I_True + 0007 I_Jump 0x0000000D (00000013) + 0012 I_False + 0013 I_Pop $ NO_COLOR="1" print_vm . Let 1 $ NO_COLOR="1" print_instructions . Let - 0000 I_Constant 0x0001 (0001) - 0003 I_Set_Global 0x0001 (0001) - 0006 I_Get_Global 0x0000 (0000) - 0009 I_Set_Global 0x0002 (0002) - 0012 I_Get_Global 0x0001 (0001) - 0015 I_Pop + 0000 I_Constant 0x00000001 (00000001) + 0005 I_Set_Global 0x00000001 (00000001) + 0010 I_Get_Global 0x00000000 (00000000) + 0015 I_Set_Global 0x00000002 (00000002) + 0020 I_Get_Global 0x00000001 (00000001) + 0025 I_Pop $ NO_COLOR="1" print_instructions . UnboundIdentifier