mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-06 06:28:39 +00:00
Implement bgt_s (#95)
This commit is contained in:
14
CLAUDE.md
14
CLAUDE.md
@@ -71,7 +71,7 @@ dotnet run --project WoofWare.PawPrint.App/WoofWare.PawPrint.App.fsproj -- CShar
|
|||||||
- Test cases are defined in `TestPureCases.fs` and `TestImpureCases.fs`
|
- Test cases are defined in `TestPureCases.fs` and `TestImpureCases.fs`
|
||||||
- C# source files in `sources{Pure,Impure}/` are compiled and executed by the runtime as test cases
|
- C# source files in `sources{Pure,Impure}/` are compiled and executed by the runtime as test cases
|
||||||
- `TestHarness.fs` provides infrastructure for running test assemblies through the interpreter
|
- `TestHarness.fs` provides infrastructure for running test assemblies through the interpreter
|
||||||
- Run all tests with `dotnet run --project WoofWare.PawPrint.Test/WoofWare.PawPrint.Test.fsproj -- --no-spinner`
|
- Run all tests with `dotnet run --project WoofWare.PawPrint.Test/WoofWare.PawPrint.Test.fsproj -- --no-spinner` (note the additional `--`)
|
||||||
- Run a specific test with `dotnet run --project WoofWare.PawPrint.Test/WoofWare.PawPrint.Test.fsproj -- --filter-test-case StringWithinTestName --no-spinner`
|
- Run a specific test with `dotnet run --project WoofWare.PawPrint.Test/WoofWare.PawPrint.Test.fsproj -- --filter-test-case StringWithinTestName --no-spinner`
|
||||||
- Pending test definitions must be moved into the non-pending test case list before they can be run.
|
- Pending test definitions must be moved into the non-pending test case list before they can be run.
|
||||||
|
|
||||||
@@ -194,10 +194,10 @@ When you need to create a `TypeDefn` from type metadata (e.g., from a `TypeInfo`
|
|||||||
|
|
||||||
This pattern is implemented in `UnaryMetadataIlOp.lookupTypeDefn`. Example usage:
|
This pattern is implemented in `UnaryMetadataIlOp.lookupTypeDefn`. Example usage:
|
||||||
```fsharp
|
```fsharp
|
||||||
let state, typeDefn =
|
let state, typeDefn =
|
||||||
UnaryMetadataIlOp.lookupTypeDefn
|
UnaryMetadataIlOp.lookupTypeDefn
|
||||||
baseClassTypes
|
baseClassTypes
|
||||||
state
|
state
|
||||||
activeAssembly
|
activeAssembly
|
||||||
typeDefHandle
|
typeDefHandle
|
||||||
```
|
```
|
||||||
@@ -222,7 +222,7 @@ When constructing objects with `Newobj`:
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
```fsharp
|
```fsharp
|
||||||
let instanceFields =
|
let instanceFields =
|
||||||
ctorType.Fields
|
ctorType.Fields
|
||||||
|> List.filter (fun field -> not (field.Attributes.HasFlag FieldAttributes.Static))
|
|> List.filter (fun field -> not (field.Attributes.HasFlag FieldAttributes.Static))
|
||||||
```
|
```
|
||||||
|
@@ -120,9 +120,14 @@ module EvalStackValueComparisons =
|
|||||||
failwith "TODO"
|
failwith "TODO"
|
||||||
| other1, other2 -> failwith $"Cgt.un instruction invalid for comparing {other1} vs {other2}"
|
| other1, other2 -> failwith $"Cgt.un instruction invalid for comparing {other1} vs {other2}"
|
||||||
|
|
||||||
let ceq (var1 : EvalStackValue) (var2 : EvalStackValue) : bool =
|
let rec ceq (var1 : EvalStackValue) (var2 : EvalStackValue) : bool =
|
||||||
// Table III.4
|
// Table III.4
|
||||||
match var1, var2 with
|
match var1, var2 with
|
||||||
|
| EvalStackValue.UserDefinedValueType [ _, u ], v -> ceq u v
|
||||||
|
| u, EvalStackValue.UserDefinedValueType [ _, v ] -> ceq u v
|
||||||
|
| EvalStackValue.UserDefinedValueType [], EvalStackValue.UserDefinedValueType [] -> true
|
||||||
|
| EvalStackValue.UserDefinedValueType _, _
|
||||||
|
| _, EvalStackValue.UserDefinedValueType _ -> failwith $"bad ceq: {var1} vs {var2}"
|
||||||
| EvalStackValue.Int32 var1, EvalStackValue.Int32 var2 -> var1 = var2
|
| EvalStackValue.Int32 var1, EvalStackValue.Int32 var2 -> var1 = var2
|
||||||
| EvalStackValue.Int32 var1, EvalStackValue.NativeInt var2 -> failwith "TODO: int32 CEQ nativeint"
|
| EvalStackValue.Int32 var1, EvalStackValue.NativeInt var2 -> failwith "TODO: int32 CEQ nativeint"
|
||||||
| EvalStackValue.Int32 _, _ -> failwith $"bad ceq: Int32 vs {var2}"
|
| EvalStackValue.Int32 _, _ -> failwith $"bad ceq: Int32 vs {var2}"
|
||||||
@@ -151,4 +156,3 @@ module EvalStackValueComparisons =
|
|||||||
| EvalStackValue.ManagedPointer var1, EvalStackValue.NativeInt var2 ->
|
| EvalStackValue.ManagedPointer var1, EvalStackValue.NativeInt var2 ->
|
||||||
failwith $"TODO (CEQ): managed pointer vs nativeint"
|
failwith $"TODO (CEQ): managed pointer vs nativeint"
|
||||||
| EvalStackValue.ManagedPointer _, _ -> failwith $"bad ceq: ManagedPointer vs {var2}"
|
| EvalStackValue.ManagedPointer _, _ -> failwith $"bad ceq: ManagedPointer vs {var2}"
|
||||||
| EvalStackValue.UserDefinedValueType _, _ -> failwith $"bad ceq: {var1} vs {var2}"
|
|
||||||
|
@@ -1369,6 +1369,9 @@ module IlMachineState =
|
|||||||
|
|
||||||
state, assy.Name, Choice1Of2 method, extractedTypeArgs
|
state, assy.Name, Choice1Of2 method, extractedTypeArgs
|
||||||
|
|
||||||
|
let getLocalVariable (thread : ThreadId) (stackFrame : int) (varIndex : uint16) (state : IlMachineState) : CliType =
|
||||||
|
state.ThreadState.[thread].MethodStates.[stackFrame].LocalVariables.[int<uint16> varIndex]
|
||||||
|
|
||||||
let setLocalVariable
|
let setLocalVariable
|
||||||
(thread : ThreadId)
|
(thread : ThreadId)
|
||||||
(stackFrame : int)
|
(stackFrame : int)
|
||||||
|
@@ -212,7 +212,33 @@ module internal UnaryConstIlOp =
|
|||||||
else
|
else
|
||||||
id
|
id
|
||||||
|> Tuple.withRight WhatWeDid.Executed
|
|> Tuple.withRight WhatWeDid.Executed
|
||||||
| Blt_s b -> failwith "TODO: Blt_s unimplemented"
|
| Blt_s b ->
|
||||||
|
let value2, state = IlMachineState.popEvalStack currentThread state
|
||||||
|
let value1, state = IlMachineState.popEvalStack currentThread state
|
||||||
|
|
||||||
|
let isLessThan =
|
||||||
|
match value1, value2 with
|
||||||
|
| EvalStackValue.Int32 v1, EvalStackValue.Int32 v2 -> v1 < v2
|
||||||
|
| EvalStackValue.Int32 i, EvalStackValue.NativeInt nativeIntSource -> failwith "todo"
|
||||||
|
| EvalStackValue.Int32 i, _ -> failwith $"invalid comparison, {i} with {value2}"
|
||||||
|
| EvalStackValue.Int64 v1, EvalStackValue.Int64 v2 -> v1 < v2
|
||||||
|
| EvalStackValue.Int64 i, _ -> failwith $"invalid comparison, {i} with {value2}"
|
||||||
|
| EvalStackValue.NativeInt nativeIntSource, _ -> failwith "todo"
|
||||||
|
| EvalStackValue.Float v1, EvalStackValue.Float v2 -> failwith "todo"
|
||||||
|
| EvalStackValue.Float f, _ -> failwith $"invalid comparison, {f} with {value2}"
|
||||||
|
| EvalStackValue.ManagedPointer v1, EvalStackValue.ManagedPointer v2 -> failwith "todo"
|
||||||
|
| EvalStackValue.ManagedPointer v1, _ -> failwith $"invalid comparison, {v1} with {value2}"
|
||||||
|
| EvalStackValue.ObjectRef _, _ -> failwith "todo"
|
||||||
|
| EvalStackValue.UserDefinedValueType _, _ ->
|
||||||
|
failwith "unexpectedly tried to compare user-defined value type"
|
||||||
|
|
||||||
|
state
|
||||||
|
|> IlMachineState.advanceProgramCounter currentThread
|
||||||
|
|> if isLessThan then
|
||||||
|
IlMachineState.jumpProgramCounter currentThread (int<int8> b)
|
||||||
|
else
|
||||||
|
id
|
||||||
|
|> Tuple.withRight WhatWeDid.Executed
|
||||||
| Ble_s b ->
|
| Ble_s b ->
|
||||||
let value2, state = IlMachineState.popEvalStack currentThread state
|
let value2, state = IlMachineState.popEvalStack currentThread state
|
||||||
let value1, state = IlMachineState.popEvalStack currentThread state
|
let value1, state = IlMachineState.popEvalStack currentThread state
|
||||||
@@ -240,7 +266,33 @@ module internal UnaryConstIlOp =
|
|||||||
else
|
else
|
||||||
id
|
id
|
||||||
|> Tuple.withRight WhatWeDid.Executed
|
|> Tuple.withRight WhatWeDid.Executed
|
||||||
| Bgt_s b -> failwith "TODO: Bgt_s unimplemented"
|
| Bgt_s b ->
|
||||||
|
let value2, state = IlMachineState.popEvalStack currentThread state
|
||||||
|
let value1, state = IlMachineState.popEvalStack currentThread state
|
||||||
|
|
||||||
|
let isGreaterThan =
|
||||||
|
match value1, value2 with
|
||||||
|
| EvalStackValue.Int32 v1, EvalStackValue.Int32 v2 -> v1 > v2
|
||||||
|
| EvalStackValue.Int32 i, EvalStackValue.NativeInt nativeIntSource -> failwith "todo"
|
||||||
|
| EvalStackValue.Int32 i, _ -> failwith $"invalid comparison, {i} with {value2}"
|
||||||
|
| EvalStackValue.Int64 v1, EvalStackValue.Int64 v2 -> v1 > v2
|
||||||
|
| EvalStackValue.Int64 i, _ -> failwith $"invalid comparison, {i} with {value2}"
|
||||||
|
| EvalStackValue.NativeInt nativeIntSource, _ -> failwith "todo"
|
||||||
|
| EvalStackValue.Float v1, EvalStackValue.Float v2 -> failwith "todo"
|
||||||
|
| EvalStackValue.Float f, _ -> failwith $"invalid comparison, {f} with {value2}"
|
||||||
|
| EvalStackValue.ManagedPointer v1, EvalStackValue.ManagedPointer v2 -> failwith "todo"
|
||||||
|
| EvalStackValue.ManagedPointer v1, _ -> failwith $"invalid comparison, {v1} with {value2}"
|
||||||
|
| EvalStackValue.ObjectRef _, _ -> failwith "todo"
|
||||||
|
| EvalStackValue.UserDefinedValueType _, _ ->
|
||||||
|
failwith "unexpectedly tried to compare user-defined value type"
|
||||||
|
|
||||||
|
state
|
||||||
|
|> IlMachineState.advanceProgramCounter currentThread
|
||||||
|
|> if isGreaterThan then
|
||||||
|
IlMachineState.jumpProgramCounter currentThread (int<int8> b)
|
||||||
|
else
|
||||||
|
id
|
||||||
|
|> Tuple.withRight WhatWeDid.Executed
|
||||||
| Bge_s b ->
|
| Bge_s b ->
|
||||||
let value2, state = IlMachineState.popEvalStack currentThread state
|
let value2, state = IlMachineState.popEvalStack currentThread state
|
||||||
let value1, state = IlMachineState.popEvalStack currentThread state
|
let value1, state = IlMachineState.popEvalStack currentThread state
|
||||||
|
Reference in New Issue
Block a user