mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-08 15:38:41 +00:00
Implement mul and a more general arithmetic mechanism (#25)
This commit is contained in:
@@ -2,11 +2,68 @@ namespace WoofWare.PawPrint
|
||||
|
||||
#nowarn "42"
|
||||
|
||||
open System.Collections.Immutable
|
||||
type private IArithmeticOperation =
|
||||
abstract Int32Int32 : int32 -> int32 -> int32
|
||||
abstract Int64Int64 : int64 -> int64 -> int64
|
||||
abstract FloatFloat : float -> float -> float
|
||||
abstract Name : string
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module private ArithmeticOperation =
|
||||
let add =
|
||||
{ new IArithmeticOperation with
|
||||
member _.Int32Int32 a b = (# "add" a b : int32 #)
|
||||
member _.Int64Int64 a b = (# "add" a b : int64 #)
|
||||
member _.FloatFloat a b = (# "add" a b : float #)
|
||||
member _.Name = "add"
|
||||
}
|
||||
|
||||
let mul =
|
||||
{ new IArithmeticOperation with
|
||||
member _.Int32Int32 a b = (# "mul" a b : int32 #)
|
||||
member _.Int64Int64 a b = (# "mul" a b : int64 #)
|
||||
member _.FloatFloat a b = (# "mul" a b : float #)
|
||||
member _.Name = "mul"
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
||||
module NullaryIlOp =
|
||||
let private binaryArithmeticOperation
|
||||
(op : IArithmeticOperation)
|
||||
(currentThread : ThreadId)
|
||||
(state : IlMachineState)
|
||||
=
|
||||
let val1, state = IlMachineState.popEvalStack currentThread state
|
||||
let val2, state = IlMachineState.popEvalStack currentThread state
|
||||
// see table at https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.add?view=net-9.0
|
||||
let result =
|
||||
match val1, val2 with
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.Int32 val2 ->
|
||||
(# "add" val1 val2 : int32 #) |> EvalStackValue.Int32
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.NativeInt val2 -> failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.ManagedPointer val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.ObjectRef val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.Int64 val1, EvalStackValue.Int64 val2 ->
|
||||
(# "add" val1 val2 : int64 #) |> EvalStackValue.Int64
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.Int32 val2 -> failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.NativeInt val2 -> failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.ManagedPointer val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.ObjectRef val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.Float val1, EvalStackValue.Float val2 ->
|
||||
(# "add" val1 val2 : float #) |> EvalStackValue.Float
|
||||
| EvalStackValue.ManagedPointer val1, EvalStackValue.NativeInt val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.ObjectRef val1, EvalStackValue.NativeInt val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.ManagedPointer val1, EvalStackValue.Int32 val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.ObjectRef val1, EvalStackValue.Int32 val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| val1, val2 -> failwith $"invalid %s{op.Name} operation: {val1} and {val2}"
|
||||
|
||||
result, state
|
||||
|
||||
let internal execute (state : IlMachineState) (currentThread : ThreadId) (op : NullaryIlOp) : ExecutionResult =
|
||||
match op with
|
||||
| Nop ->
|
||||
@@ -257,36 +314,8 @@ module NullaryIlOp =
|
||||
| Sub_ovf -> failwith "TODO: Sub_ovf unimplemented"
|
||||
| Sub_ovf_un -> failwith "TODO: Sub_ovf_un unimplemented"
|
||||
| Add ->
|
||||
let val1, state = IlMachineState.popEvalStack currentThread state
|
||||
let val2, state = IlMachineState.popEvalStack currentThread state
|
||||
// see table at https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.add?view=net-9.0
|
||||
let result =
|
||||
match val1, val2 with
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.Int32 val2 ->
|
||||
(# "add" val1 val2 : int32 #) |> EvalStackValue.Int32
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.NativeInt val2 -> failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.ManagedPointer val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.Int32 val1, EvalStackValue.ObjectRef val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.Int64 val1, EvalStackValue.Int64 val2 ->
|
||||
(# "add" val1 val2 : int64 #) |> EvalStackValue.Int64
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.Int32 val2 -> failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.NativeInt val2 ->
|
||||
failwith "" |> EvalStackValue.NativeInt
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.ManagedPointer val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.NativeInt val1, EvalStackValue.ObjectRef val2 ->
|
||||
failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.Float val1, EvalStackValue.Float val2 ->
|
||||
(# "add" val1 val2 : float #) |> EvalStackValue.Float
|
||||
| EvalStackValue.ManagedPointer val1, EvalStackValue.NativeInt val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.ObjectRef val1, EvalStackValue.NativeInt val2 ->
|
||||
failwith "" |> EvalStackValue.ObjectRef
|
||||
| EvalStackValue.ManagedPointer val1, EvalStackValue.Int32 val2 ->
|
||||
failwith "" |> EvalStackValue.ManagedPointer
|
||||
| EvalStackValue.ObjectRef val1, EvalStackValue.Int32 val2 -> failwith "" |> EvalStackValue.ObjectRef
|
||||
| val1, val2 -> failwith $"invalid add operation: {val1} and {val2}"
|
||||
let result, state =
|
||||
binaryArithmeticOperation ArithmeticOperation.add currentThread state
|
||||
|
||||
state
|
||||
|> IlMachineState.pushToEvalStack' result currentThread
|
||||
@@ -295,7 +324,15 @@ module NullaryIlOp =
|
||||
|> ExecutionResult.Stepped
|
||||
| Add_ovf -> failwith "TODO: Add_ovf unimplemented"
|
||||
| Add_ovf_un -> failwith "TODO: Add_ovf_un unimplemented"
|
||||
| Mul -> failwith "TODO: Mul unimplemented"
|
||||
| Mul ->
|
||||
let result, state =
|
||||
binaryArithmeticOperation ArithmeticOperation.mul currentThread state
|
||||
|
||||
state
|
||||
|> IlMachineState.pushToEvalStack' result currentThread
|
||||
|> IlMachineState.advanceProgramCounter currentThread
|
||||
|> Tuple.withRight WhatWeDid.Executed
|
||||
|> ExecutionResult.Stepped
|
||||
| Mul_ovf -> failwith "TODO: Mul_ovf unimplemented"
|
||||
| Mul_ovf_un -> failwith "TODO: Mul_ovf_un unimplemented"
|
||||
| Div -> failwith "TODO: Div unimplemented"
|
||||
|
Reference in New Issue
Block a user