Skip to content

Commit 462f231

Browse files
authored
Option evaluation (#250)
* Added target test * Added evaultion of `Some(...)` and `None` * Removed `ArgumentList` as it was a duplicate of `OperandList` * Added evaluation of `Option<...>::unwrap()` Uses internal function `#unwrap(...)` as an executed `Statement` before executing next basic block. Passes 6 more tests, however many failing tests have changed from `4` to `113`. I believe this is not actually because of this commit, but because this commit has allowed the test to get further to run into other issues. * Added test to demonstrate `match` works * Whitelisted `Option` keywords * Added `main` to `Whitelisted` * Added token attribute to `Whitelisted` * Removed `Whitespace` production. Using IdentifierToken instead. * Refactored token declarations to be by relevant semantics.
1 parent 263aff7 commit 462f231

10 files changed

+181
-47
lines changed

kmir/k-src/mir-lexer-syntax.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ This module defined the necessary `token` productions.
99
| LocalToken
1010
| BBId
1111
| DoubleHexDigitNoIntLetter
12-
| Whitelisted
1312
14-
syntax Whitelisted ::= "transmute" | "unwind" | "count"
13+
syntax IdentifierToken ::= "transmute" [token]
14+
| "unwind" [token]
15+
| "count" [token]
1516
1617
syntax String ::= IdentifierToken2String(IdentifierToken) [function, hook(STRING.token2string)]
1718
syntax IdentifierToken ::= StringIdentifierToken(String) [function, hook(STRING.string2token)]

kmir/k-src/mir-rvalue.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ The various kinds of rvalues that can appear in MIR.
119119
// `AssertKind` `Eq`, `Ne` conflict with BinaryOp names https://github.com/rust-lang/rust/blob/f562931178ff103f23b9e9a10dc0deb38e0d064f/library/core/src/panicking.rs#L259-L263
120120
syntax EnumConstructor ::= Identifier
121121
| Identifier "(" OperandList ")"
122-
| PathExpression "::" Identifier
122+
| PathExpression "::" Identifier [avoid]
123123
| PathExpression "::" "Eq"
124124
| PathExpression "::" "Ne"
125125
// | PathExpression "::" "Match" // Match isn't conflicting at the moment but might later
@@ -138,6 +138,8 @@ The various kinds of rvalues that can appear in MIR.
138138
syntax OperandList ::= List{Operand, ","}
139139
140140
syntax PtrModifiers ::= "" | "mut" | "raw" "mut" | "raw" "const"
141+
142+
syntax RValue ::= #unwrap(Operand)
141143
```
142144

143145
```k
@@ -166,7 +168,10 @@ Evaluate a syntactic `RValue` into a semantics `RValueResult`. Inspired by [eval
166168
rule evalRValue(FN_KEY, ADDR:AddressOf) => evalAddressOf(FN_KEY, ADDR)
167169
rule evalRValue(FN_KEY, CFD:CopyForDeref) => evalCopyForDeref(FN_KEY, CFD)
168170
rule evalRValue(FN_KEY, TUP:Tuple) => evalTuple(FN_KEY, TUP)
171+
rule evalRValue(FN_KEY, ENUM:EnumConstructor) => evalEnumConstructor(FN_KEY, ENUM) [priority(51)]
169172
rule evalRValue(_FN_KEY, RVALUE) => Unsupported(RVALUE) [owise]
173+
174+
rule evalRValue(FN_KEY, #unwrap(OP)) => evalUnwrap(evalOperand(FN_KEY, OP))
170175
```
171176

172177
### `Operand` evaluation
@@ -364,6 +369,26 @@ Locals only makes sense within a function-like, hence we evaluate them as a cont
364369
requires PLACE_INDEX ==Int Local2Int(PLACE)
365370
```
366371

372+
### `Enum` evaluation
373+
```k
374+
syntax IdentifierToken ::= "Option" [token]
375+
| "None" [token]
376+
| "Some" [token]
377+
| "unwrap" [token]
378+
379+
syntax MIRValue ::= evalEnumConstructor(FunctionLikeKey, EnumConstructor) [function]
380+
//--------------------------------------------------------------
381+
rule evalEnumConstructor( FN_KEY, Option :: < _TYPES > :: .ExpressionPathList :: Some ( OP , .OperandList ) ) => OptSome(evalOperand(FN_KEY, OP:Operand))
382+
rule evalEnumConstructor(_FN_KEY, Option :: < _TYPES > :: .ExpressionPathList :: None ) => OptNone
383+
```
384+
385+
### Internal Functions
386+
```k
387+
syntax MIRValue ::= evalUnwrap(MIRValue) [function]
388+
//-------------------------------------------------
389+
rule evalUnwrap(OptSome( VALUE:MIRValue )) => VALUE
390+
```
391+
367392
```k
368393
endmodule
369394
```

kmir/k-src/mir-terminator.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,13 @@ These constructs need to be disambiguated at runtime. See the `MIR-AMBIGUITIES`
5959
syntax SwitchTargets ::= List{SwitchTarget, ","}
6060
syntax SwitchTarget ::= Int ":" BB
6161
62-
syntax CallLike ::= Callable "(" ArgumentList ")" | AssertCall
62+
syntax CallLike ::= Callable "(" OperandList ")" | AssertCall
6363
6464
syntax Callable ::= PathExpression
6565
| "move" Local
6666
6767
syntax AssertCall ::= "assert" "(" AssertArgument "," AssertKind ")"
68-
// syntax AssertCall ::= "assert" "(" AssertArgumentList ")"
69-
syntax AssertArgument ::= Operand | "!" Operand // | StringLiteral
70-
// syntax AssertArgumentList ::= NeList{AssertArgument, ","}
71-
72-
syntax ArgumentList ::= List{Operand, ","}
68+
syntax AssertArgument ::= Operand | "!" Operand
7369
7470
syntax TerminatorDestination ::= BB | SwitchIntCases | CallDestination | AssertDestination
7571
syntax SwitchIntCases ::= "[" IntCaseList "," OtherwiseCase "]"

kmir/k-src/mir-types.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,9 +450,12 @@ TODO: add more domain sorts
450450
| Bool
451451
| "Never"
452452
| TupleArgs
453+
| OptionVal
453454
| "UNIMPLEMENTED"
454455
455456
syntax TupleArgs ::= "(" MIRValueNeList ")"
457+
syntax OptionVal ::= "OptSome" "(" MIRValue ")"
458+
| "OptNone"
456459
457460
syntax RValueResult ::= MIRValue
458461

kmir/k-src/mir.md

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ The presence of the empty program, `.Mir`, on the `<k>` cell indicates that the
3333
```k
3434
rule <k> .Mir => #initialized() ... </k>
3535
<phase> Initialization </phase>
36-
rule <k> #initialized() => #executeFunctionLike(Fn(String2IdentifierToken("main"):: .FunctionPath), .ArgumentList) ... </k>
36+
rule <k> #initialized() => #executeFunctionLike(Fn(main :: .FunctionPath), .OperandList) ... </k>
3737
<phase> Initialization => Execution </phase>
3838
```
3939

@@ -45,11 +45,11 @@ If we are, then we stop execution and enter the finalization phase. Otherwise, i
4545
<callStack> ListItem(FUNCTION_KEY) => .List </callStack>
4646
<phase> Execution => Finalization </phase>
4747
<returncode> _ => 0 </returncode>
48-
requires FUNCTION_KEY ==K Fn(String2IdentifierToken("main"))
48+
requires FUNCTION_KEY ==K Fn(main)
4949
5050
rule <k> #return(FUNCTION_KEY, _) => .K ... </k>
5151
<callStack> ListItem(FUNCTION_KEY) XS => XS </callStack>
52-
requires FUNCTION_KEY =/=K Fn(String2IdentifierToken("main"))
52+
requires FUNCTION_KEY =/=K Fn(main)
5353
endmodule
5454
```
5555

@@ -310,14 +310,16 @@ Executing a function-like means:
310310
Note that the `main` function is special: it does not have a caller.
311311

312312
```k
313-
syntax MirSimulation ::= #executeFunctionLike(FunctionLikeKey, ArgumentList)
313+
syntax IdentifierToken ::= "main" [token]
314+
315+
syntax MirSimulation ::= #executeFunctionLike(FunctionLikeKey, OperandList)
314316
//--------------------------------------------------------------------------
315317
rule <k> #executeFunctionLike(FN_KEY, _ARGS)
316318
=> #executeBasicBlock(FN_KEY, 0)
317319
...
318320
</k>
319321
<callStack> .List => ListItem(FN_KEY) </callStack>
320-
requires FN_KEY ==K Fn(String2IdentifierToken("main"):: .FunctionPath)
322+
requires FN_KEY ==K Fn(main :: .FunctionPath)
321323
rule <k> #executeFunctionLike(CALLEE_FN_KEY, ARGS)
322324
=> #instantiateArguments(CALLER_FN_KEY, ARGS, 1)
323325
~> #executeBasicBlock(CALLEE_FN_KEY, 0)
@@ -337,7 +339,7 @@ Note that the `main` function is special: it does not have a caller.
337339
<callStack> ListItem(Rec(PATH, _)) _STACK </callStack> [priority(49)]
338340
339341
// TODO: Either save unimplemented stack frame for correct initial values, or clear values
340-
syntax MirSimulation ::= #addRecursiveFrame(FunctionLikeKey, ArgumentList)
342+
syntax MirSimulation ::= #addRecursiveFrame(FunctionLikeKey, OperandList)
341343
//-------------------------------------------------------------------------
342344
rule <k> #addRecursiveFrame(Fn(PATH), ARGS)
343345
=> #instantiateArguments(Rec(PATH, 0), ARGS, 1)
@@ -364,10 +366,10 @@ Note that the `main` function is special: it does not have a caller.
364366
Assign arguments (actual parameters) to formal parameters of a function-like:
365367

366368
```k
367-
syntax MirSimulation ::= #instantiateArguments(FunctionLikeKey, ArgumentList, Int)
369+
syntax MirSimulation ::= #instantiateArguments(FunctionLikeKey, OperandList, Int)
368370
//--------------------------------------------------------------------------------
369-
rule <k> #instantiateArguments(_FN_KEY, .ArgumentList, _) => .K ... </k>
370-
rule <k> #instantiateArguments(FN_KEY, (ARG, REST):ArgumentList, ARGUMENT_NUMBER:Int)
371+
rule <k> #instantiateArguments(_FN_KEY, .OperandList, _) => .K ... </k>
372+
rule <k> #instantiateArguments(FN_KEY, (ARG, REST):OperandList, ARGUMENT_NUMBER:Int)
371373
=> #writeLocal(CALLEE_FN_KEY, Int2Local(ARGUMENT_NUMBER), evalOperand(CALLER_FN_KEY, ARG))
372374
~> #instantiateArguments(FN_KEY, REST, ARGUMENT_NUMBER +Int 1)
373375
...
@@ -489,32 +491,38 @@ or panics if the function-like or the block is missing:
489491
...
490492
</k>
491493
<callStack> ListItem(Fn(FNAME)) ... </callStack>
492-
requires FNAME ==K toFunctionPath(OTHER_FN_NAME) [priority(49)]
494+
requires FNAME ==K toFunctionPath(OTHER_FN_NAME) [priority(49)]
493495
rule <k> #executeTerminator(DEST_LOCAL:Local = OTHER_FN_NAME:PathInExpression ( ARGS ) -> ((NEXT:BBName _):BB))
494496
=> #executeFunctionLike(Fn(toFunctionPath(OTHER_FN_NAME)), ARGS)
495497
~> #transferLocal(Rec(toFunctionPath(OTHER_FN_NAME), DEPTH +Int 1), Int2Local(0), Rec(FNAME, DEPTH), DEST_LOCAL)
496498
~> #executeBasicBlock(Rec(FNAME, DEPTH), BBName2Int(NEXT))
497499
...
498500
</k>
499501
<callStack> ListItem(Rec(FNAME, DEPTH)) ... </callStack>
500-
requires FNAME ==K toFunctionPath(OTHER_FN_NAME) [priority(49)]
502+
requires FNAME ==K toFunctionPath(OTHER_FN_NAME) [priority(49)]
501503
rule <k> #executeTerminator(switchInt (ARG:Operand) -> [ TARGETS:SwitchTargets , otherwise : OTHERWISE:BB ])
502504
=> #switchInt(FN_KEY, castMIRValueToInt(evalOperand(FN_KEY, ARG)), TARGETS, OTHERWISE)
503505
...
504506
</k>
505507
<callStack> ListItem(FN_KEY) ... </callStack>
506508
requires isInt(castMIRValueToInt(evalOperand(FN_KEY, ARG)))
507-
rule <k> #executeTerminator(_:Local = PANIC_CALL (ARG, .ArgumentList))
509+
rule <k> #executeTerminator(_:Local = PANIC_CALL (ARG, .OperandList))
508510
=> #panic(FN_KEY, PanicCall, ARG)
509511
...
510512
</k>
511513
<callStack> ListItem(FN_KEY) ... </callStack>
512-
requires PANIC_CALL ==K String2IdentifierToken("core") :: String2IdentifierToken("panicking") :: String2IdentifierToken("panic") :: .ExpressionPathList
514+
requires PANIC_CALL ==K String2IdentifierToken("core") :: String2IdentifierToken("panicking") :: String2IdentifierToken("panic") :: .ExpressionPathList
513515
rule <k> #executeTerminator(TERMIANTOR:Terminator)
514516
=> #internalPanic(FN_KEY, NotImplemented, TERMIANTOR)
515517
...
516518
</k>
517519
<callStack> ListItem(FN_KEY) ... </callStack> [owise]
520+
521+
// Option Unwrap Call
522+
rule <k> #executeTerminator(DEST_LOCAL:Local = Option :: < _TYPES > :: unwrap :: .ExpressionPathList ( ARG , .OperandList ) -> ((NEXT:BBName _):BB))
523+
=> #executeStatement(DEST_LOCAL = #unwrap(ARG)) ~> #executeBasicBlock(FN_KEY, BBName2Int(NEXT)) ...
524+
</k>
525+
<callStack> ListItem(FN_KEY) ... </callStack> [priority(48)]
518526
```
519527

520528
The following rule executes exists to copy a value of one local to another local, the locals may belong to different functions.

0 commit comments

Comments
 (0)