mirror of
https://github.com/anoma/juvix.git
synced 2024-12-26 09:04:18 +03:00
parent
8e204634b8
commit
26ea94b977
@ -70,10 +70,6 @@ calculateInterest : Nat -> Nat -> Nat -> Nat
|
|||||||
incrAmount (a : Nat) : Nat := div (a * rate) 10000;
|
incrAmount (a : Nat) : Nat := div (a * rate) 10000;
|
||||||
in iterate (min 100 periods) incrAmount amount;
|
in iterate (min 100 periods) incrAmount amount;
|
||||||
|
|
||||||
--- Asserts some ;Bool; condition.
|
|
||||||
assert : {A : Type} -> Bool -> A -> A
|
|
||||||
| c a := ite c a (failwith "assertion failed");
|
|
||||||
|
|
||||||
--- Returns a new ;Token;. Arguments are:
|
--- Returns a new ;Token;. Arguments are:
|
||||||
---
|
---
|
||||||
--- `owner`: The address of the account to issue the token to
|
--- `owner`: The address of the account to issue the token to
|
||||||
@ -82,7 +78,7 @@ assert : {A : Type} -> Bool -> A -> A
|
|||||||
---
|
---
|
||||||
--- `caller`: Who is creating the transaction. It must be the bank.
|
--- `caller`: Who is creating the transaction. It must be the bank.
|
||||||
issue : Address -> Address -> Nat -> Token
|
issue : Address -> Address -> Nat -> Token
|
||||||
| caller owner amount := assert (caller == bankAddress) (mkToken owner 0 amount);
|
| caller owner amount := assert (caller == bankAddress) >-> mkToken owner 0 amount;
|
||||||
|
|
||||||
--- Deposits some amount of money into the bank.
|
--- Deposits some amount of money into the bank.
|
||||||
deposit (bal : Balances) (token : Token) (amount : Nat) : Token :=
|
deposit (bal : Balances) (token : Token) (amount : Nat) : Token :=
|
||||||
@ -102,11 +98,10 @@ withdraw
|
|||||||
(rate : Nat)
|
(rate : Nat)
|
||||||
(periods : Nat)
|
(periods : Nat)
|
||||||
: Token :=
|
: Token :=
|
||||||
assert
|
assert (caller == bankAddress)
|
||||||
(caller == bankAddress)
|
>-> let
|
||||||
(let
|
hash : Field := hashAddress recipient;
|
||||||
hash : Field := hashAddress recipient;
|
total : Nat := calculateInterest amount rate periods;
|
||||||
total : Nat := calculateInterest amount rate periods;
|
token : Token := mkToken recipient 0 total;
|
||||||
token : Token := mkToken recipient 0 total;
|
bal' : Balances := decrement hash amount bal;
|
||||||
bal' : Balances := decrement hash amount bal;
|
in runOnChain (commitBalances bal') token;
|
||||||
in runOnChain (commitBalances bal') token);
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 615a02c8107076ca9661c5234d41792be91a5104
|
Subproject commit 6010ad32f80498432b9a14752a0b7b50e9b36763
|
@ -104,6 +104,7 @@ closure_label:
|
|||||||
#define JUVIX_INT_TO_UINT8(var0, var1) \
|
#define JUVIX_INT_TO_UINT8(var0, var1) \
|
||||||
(var0 = make_smallint((word_t)((uint8_t)(get_unboxed_int(var1) & 0xFF))))
|
(var0 = make_smallint((word_t)((uint8_t)(get_unboxed_int(var1) & 0xFF))))
|
||||||
|
|
||||||
|
#define JUVIX_ASSERT(val) (assert(is_true(val)))
|
||||||
#define JUVIX_TRACE(val) (io_trace(val))
|
#define JUVIX_TRACE(val) (io_trace(val))
|
||||||
#define JUVIX_DUMP (stacktrace_dump())
|
#define JUVIX_DUMP (stacktrace_dump())
|
||||||
#define JUVIX_FAILURE(val) \
|
#define JUVIX_FAILURE(val) \
|
||||||
|
@ -92,6 +92,8 @@ recurse' sig = go True
|
|||||||
throw $
|
throw $
|
||||||
AsmError loc "popping empty value stack"
|
AsmError loc "popping empty value stack"
|
||||||
return (popValueStack 1 mem)
|
return (popValueStack 1 mem)
|
||||||
|
Assert ->
|
||||||
|
return mem
|
||||||
Trace ->
|
Trace ->
|
||||||
return mem
|
return mem
|
||||||
Dump ->
|
Dump ->
|
||||||
@ -412,6 +414,8 @@ recurseS' sig = go True
|
|||||||
return (stackInfoPushValueStack 1 si)
|
return (stackInfoPushValueStack 1 si)
|
||||||
Pop -> do
|
Pop -> do
|
||||||
return (stackInfoPopValueStack 1 si)
|
return (stackInfoPopValueStack 1 si)
|
||||||
|
Assert ->
|
||||||
|
return si
|
||||||
Trace ->
|
Trace ->
|
||||||
return si
|
return si
|
||||||
Dump ->
|
Dump ->
|
||||||
|
@ -82,6 +82,11 @@ runCodeR infoTable funInfo = goCode (funInfo ^. functionCode) >> popLastValueSta
|
|||||||
goCode cont
|
goCode cont
|
||||||
Pop ->
|
Pop ->
|
||||||
popValueStack >> goCode cont
|
popValueStack >> goCode cont
|
||||||
|
Assert -> do
|
||||||
|
v <- topValueStack
|
||||||
|
unless (v == ValBool True) $
|
||||||
|
runtimeError "assertion failed"
|
||||||
|
goCode cont
|
||||||
Trace -> do
|
Trace -> do
|
||||||
v <- topValueStack
|
v <- topValueStack
|
||||||
logMessage (printValue infoTable v)
|
logMessage (printValue infoTable v)
|
||||||
|
@ -49,6 +49,9 @@ data Instruction
|
|||||||
Push Value
|
Push Value
|
||||||
| -- | Pop the stack. JVA opcode: 'pop'.
|
| -- | Pop the stack. JVA opcode: 'pop'.
|
||||||
Pop
|
Pop
|
||||||
|
| -- | Assert a boolean on top of the stack. Does not pop the stack. JVA
|
||||||
|
-- opcode: 'assert'.
|
||||||
|
Assert
|
||||||
| -- | Print a debug log of the object on top of the stack. Does not pop the
|
| -- | Print a debug log of the object on top of the stack. Does not pop the
|
||||||
-- stack. JVA opcode: 'trace'.
|
-- stack. JVA opcode: 'trace'.
|
||||||
Trace
|
Trace
|
||||||
|
@ -98,6 +98,7 @@ instance PrettyCode Instruction where
|
|||||||
Cairo op -> Tree.ppCode op
|
Cairo op -> Tree.ppCode op
|
||||||
Push val -> (primitive Str.instrPush <+>) <$> ppCode val
|
Push val -> (primitive Str.instrPush <+>) <$> ppCode val
|
||||||
Pop -> return $ primitive Str.instrPop
|
Pop -> return $ primitive Str.instrPop
|
||||||
|
Assert -> return $ primitive Str.instrAssert
|
||||||
Trace -> return $ primitive Str.instrTrace
|
Trace -> return $ primitive Str.instrTrace
|
||||||
Dump -> return $ primitive Str.instrDump
|
Dump -> return $ primitive Str.instrDump
|
||||||
Failure -> return $ primitive Str.instrFailure
|
Failure -> return $ primitive Str.instrFailure
|
||||||
|
@ -91,6 +91,8 @@ command = do
|
|||||||
mkInstr' loc . Push <$> value
|
mkInstr' loc . Push <$> value
|
||||||
"pop" ->
|
"pop" ->
|
||||||
return $ mkInstr' loc Pop
|
return $ mkInstr' loc Pop
|
||||||
|
"assert" ->
|
||||||
|
return $ mkInstr' loc Assert
|
||||||
"trace" ->
|
"trace" ->
|
||||||
return $ mkInstr' loc Trace
|
return $ mkInstr' loc Trace
|
||||||
"dump" ->
|
"dump" ->
|
||||||
|
@ -233,6 +233,7 @@ genCode fi =
|
|||||||
genUnOp :: Tree.UnaryOpcode -> Command
|
genUnOp :: Tree.UnaryOpcode -> Command
|
||||||
genUnOp op = case op of
|
genUnOp op = case op of
|
||||||
Tree.PrimUnop op' -> mkUnop op'
|
Tree.PrimUnop op' -> mkUnop op'
|
||||||
|
Tree.OpAssert -> mkInstr Assert
|
||||||
Tree.OpTrace -> mkInstr Trace
|
Tree.OpTrace -> mkInstr Trace
|
||||||
Tree.OpFail -> mkInstr Failure
|
Tree.OpFail -> mkInstr Failure
|
||||||
|
|
||||||
|
@ -227,6 +227,8 @@ fromRegInstr bNoStack info = \case
|
|||||||
unsupported "Cairo builtin"
|
unsupported "Cairo builtin"
|
||||||
Reg.Assign Reg.InstrAssign {..} ->
|
Reg.Assign Reg.InstrAssign {..} ->
|
||||||
return $ stmtsAssign (fromVarRef _instrAssignResult) (fromValue _instrAssignValue)
|
return $ stmtsAssign (fromVarRef _instrAssignResult) (fromValue _instrAssignValue)
|
||||||
|
Reg.Assert Reg.InstrAssert {..} ->
|
||||||
|
return [StatementExpr $ macroCall "JUVIX_ASSERT" [fromValue _instrAssertValue]]
|
||||||
Reg.Trace Reg.InstrTrace {..} ->
|
Reg.Trace Reg.InstrTrace {..} ->
|
||||||
return [StatementExpr $ macroCall "JUVIX_TRACE" [fromValue _instrTraceValue]]
|
return [StatementExpr $ macroCall "JUVIX_TRACE" [fromValue _instrTraceValue]]
|
||||||
Reg.Dump ->
|
Reg.Dump ->
|
||||||
|
@ -43,6 +43,7 @@ fromCasm instrs0 =
|
|||||||
Casm.Return -> goReturn
|
Casm.Return -> goReturn
|
||||||
Casm.Alloc x -> goAlloc x
|
Casm.Alloc x -> goAlloc x
|
||||||
Casm.Hint x -> goHint x
|
Casm.Hint x -> goHint x
|
||||||
|
Casm.Assert x -> goAssert x
|
||||||
Casm.Trace {} -> []
|
Casm.Trace {} -> []
|
||||||
Casm.Label {} -> []
|
Casm.Label {} -> []
|
||||||
Casm.Nop -> []
|
Casm.Nop -> []
|
||||||
@ -230,6 +231,14 @@ fromCasm instrs0 =
|
|||||||
. set instrApUpdate ApUpdateAdd
|
. set instrApUpdate ApUpdateAdd
|
||||||
$ defaultInstruction
|
$ defaultInstruction
|
||||||
|
|
||||||
|
goAssert :: Casm.InstrAssert -> [Element]
|
||||||
|
goAssert Casm.InstrAssert {..} =
|
||||||
|
toElems
|
||||||
|
. updateOps False (Casm.Val (Casm.Imm 0))
|
||||||
|
. updateDst _instrAssertValue
|
||||||
|
. set instrOpcode AssertEq
|
||||||
|
$ defaultInstruction
|
||||||
|
|
||||||
goHint :: Casm.Hint -> [Element]
|
goHint :: Casm.Hint -> [Element]
|
||||||
goHint = \case
|
goHint = \case
|
||||||
Casm.HintInput var -> [ElementHint (Hint ("Input(" <> var <> ")"))]
|
Casm.HintInput var -> [ElementHint (Hint ("Input(" <> var <> ")"))]
|
||||||
|
@ -130,6 +130,8 @@ fromRegInstr info = \case
|
|||||||
unsupported "Cairo builtin"
|
unsupported "Cairo builtin"
|
||||||
Reg.Assign Reg.InstrAssign {..} ->
|
Reg.Assign Reg.InstrAssign {..} ->
|
||||||
stmtsAssign (mkVarRef _instrAssignResult) (fromValue _instrAssignValue)
|
stmtsAssign (mkVarRef _instrAssignResult) (fromValue _instrAssignValue)
|
||||||
|
Reg.Assert {} ->
|
||||||
|
unsupported "assert"
|
||||||
Reg.Trace {} ->
|
Reg.Trace {} ->
|
||||||
unsupported "trace"
|
unsupported "trace"
|
||||||
Reg.Dump ->
|
Reg.Dump ->
|
||||||
|
24
src/Juvix/Compiler/Builtins/Assert.hs
Normal file
24
src/Juvix/Compiler/Builtins/Assert.hs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
module Juvix.Compiler.Builtins.Assert where
|
||||||
|
|
||||||
|
import Juvix.Compiler.Internal.Builtins
|
||||||
|
import Juvix.Compiler.Internal.Extra
|
||||||
|
import Juvix.Prelude
|
||||||
|
|
||||||
|
checkAssert :: (Members '[Reader BuiltinsTable, Error ScoperError, NameIdGen] r) => FunctionDef -> Sem r ()
|
||||||
|
checkAssert f = do
|
||||||
|
bool_ <- getBuiltinNameScoper (getLoc f) BuiltinBool
|
||||||
|
let assert_ = f ^. funDefName
|
||||||
|
l = getLoc f
|
||||||
|
varx <- freshVar l "x"
|
||||||
|
let x = toExpression varx
|
||||||
|
assertClauses :: [(Expression, Expression)]
|
||||||
|
assertClauses = [(assert_ @@ x, x)]
|
||||||
|
checkBuiltinFunctionInfo
|
||||||
|
FunInfo
|
||||||
|
{ _funInfoDef = f,
|
||||||
|
_funInfoBuiltin = BuiltinAssert,
|
||||||
|
_funInfoSignature = bool_ --> bool_,
|
||||||
|
_funInfoClauses = assertClauses,
|
||||||
|
_funInfoFreeVars = [varx],
|
||||||
|
_funInfoFreeTypeVars = []
|
||||||
|
}
|
@ -64,6 +64,7 @@ hRunCode hout inputInfo (LabelInfo labelInfo) instrs0 = runST goCode
|
|||||||
Call x -> goCall x pc ap fp mem
|
Call x -> goCall x pc ap fp mem
|
||||||
Return -> goReturn pc ap fp mem
|
Return -> goReturn pc ap fp mem
|
||||||
Alloc x -> goAlloc x pc ap fp mem
|
Alloc x -> goAlloc x pc ap fp mem
|
||||||
|
Assert x -> goAssert x pc ap fp mem
|
||||||
Trace x -> goTrace x pc ap fp mem
|
Trace x -> goTrace x pc ap fp mem
|
||||||
Hint x -> goHint x pc ap fp mem
|
Hint x -> goHint x pc ap fp mem
|
||||||
Label {} -> go (pc + 1) ap fp mem
|
Label {} -> go (pc + 1) ap fp mem
|
||||||
@ -244,6 +245,13 @@ hRunCode hout inputInfo (LabelInfo labelInfo) instrs0 = runST goCode
|
|||||||
v <- readRValue ap fp mem _instrAllocSize
|
v <- readRValue ap fp mem _instrAllocSize
|
||||||
go (pc + 1) (ap + fromInteger (fieldToInteger v)) fp mem
|
go (pc + 1) (ap + fromInteger (fieldToInteger v)) fp mem
|
||||||
|
|
||||||
|
goAssert :: InstrAssert -> Address -> Address -> Address -> Memory s -> ST s FField
|
||||||
|
goAssert InstrAssert {..} pc ap fp mem = do
|
||||||
|
v <- readMemRef ap fp mem _instrAssertValue
|
||||||
|
when (fieldToInteger v /= 0) $
|
||||||
|
throwRunError "assertion failed"
|
||||||
|
go (pc + 1) ap fp mem
|
||||||
|
|
||||||
goTrace :: InstrTrace -> Address -> Address -> Address -> Memory s -> ST s FField
|
goTrace :: InstrTrace -> Address -> Address -> Address -> Memory s -> ST s FField
|
||||||
goTrace InstrTrace {..} pc ap fp mem = do
|
goTrace InstrTrace {..} pc ap fp mem = do
|
||||||
v <- readRValue ap fp mem _instrTraceValue
|
v <- readRValue ap fp mem _instrTraceValue
|
||||||
|
@ -11,6 +11,7 @@ import Juvix.Data.Keyword.All
|
|||||||
kwAbs,
|
kwAbs,
|
||||||
kwAp,
|
kwAp,
|
||||||
kwApPlusPlus,
|
kwApPlusPlus,
|
||||||
|
kwAssert,
|
||||||
kwCall,
|
kwCall,
|
||||||
kwColon,
|
kwColon,
|
||||||
kwDiv,
|
kwDiv,
|
||||||
@ -45,6 +46,7 @@ allKeywords =
|
|||||||
kwAbs,
|
kwAbs,
|
||||||
kwAp,
|
kwAp,
|
||||||
kwApPlusPlus,
|
kwApPlusPlus,
|
||||||
|
kwAssert,
|
||||||
kwCall,
|
kwCall,
|
||||||
kwColon,
|
kwColon,
|
||||||
kwDiv,
|
kwDiv,
|
||||||
|
@ -90,6 +90,7 @@ data Instruction
|
|||||||
| Call InstrCall
|
| Call InstrCall
|
||||||
| Return
|
| Return
|
||||||
| Alloc InstrAlloc
|
| Alloc InstrAlloc
|
||||||
|
| Assert InstrAssert
|
||||||
| Trace InstrTrace
|
| Trace InstrTrace
|
||||||
| Hint Hint
|
| Hint Hint
|
||||||
| Label LabelRef
|
| Label LabelRef
|
||||||
@ -132,6 +133,10 @@ newtype InstrAlloc = InstrAlloc
|
|||||||
{ _instrAllocSize :: RValue
|
{ _instrAllocSize :: RValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newtype InstrAssert = InstrAssert
|
||||||
|
{ _instrAssertValue :: MemRef
|
||||||
|
}
|
||||||
|
|
||||||
newtype InstrTrace = InstrTrace
|
newtype InstrTrace = InstrTrace
|
||||||
{ _instrTraceValue :: RValue
|
{ _instrTraceValue :: RValue
|
||||||
}
|
}
|
||||||
@ -148,4 +153,5 @@ makeLenses ''InstrJump
|
|||||||
makeLenses ''InstrJumpIf
|
makeLenses ''InstrJumpIf
|
||||||
makeLenses ''InstrCall
|
makeLenses ''InstrCall
|
||||||
makeLenses ''InstrAlloc
|
makeLenses ''InstrAlloc
|
||||||
|
makeLenses ''InstrAssert
|
||||||
makeLenses ''InstrTrace
|
makeLenses ''InstrTrace
|
||||||
|
@ -171,6 +171,11 @@ instance PrettyCode InstrAlloc where
|
|||||||
s <- ppCode _instrAllocSize
|
s <- ppCode _instrAllocSize
|
||||||
return $ Str.ap <+> Str.plusequal <+> s
|
return $ Str.ap <+> Str.plusequal <+> s
|
||||||
|
|
||||||
|
instance PrettyCode InstrAssert where
|
||||||
|
ppCode InstrAssert {..} = do
|
||||||
|
v <- ppCode _instrAssertValue
|
||||||
|
return $ Str.assert_ <+> v
|
||||||
|
|
||||||
instance PrettyCode InstrTrace where
|
instance PrettyCode InstrTrace where
|
||||||
ppCode InstrTrace {..} = do
|
ppCode InstrTrace {..} = do
|
||||||
v <- ppCode _instrTraceValue
|
v <- ppCode _instrTraceValue
|
||||||
@ -185,6 +190,7 @@ instance PrettyCode Instruction where
|
|||||||
Call x -> ppCode x
|
Call x -> ppCode x
|
||||||
Return -> return Str.ret
|
Return -> return Str.ret
|
||||||
Alloc x -> ppCode x
|
Alloc x -> ppCode x
|
||||||
|
Assert x -> ppCode x
|
||||||
Trace x -> ppCode x
|
Trace x -> ppCode x
|
||||||
Hint x -> ppCode x
|
Hint x -> ppCode x
|
||||||
Label x -> (<> colon) <$> ppCode x
|
Label x -> (<> colon) <$> ppCode x
|
||||||
|
@ -286,6 +286,7 @@ fromReg tab = mkResult $ run $ runLabelInfoBuilderWithNextId (Reg.getNextSymbolI
|
|||||||
Reg.Assign x -> goAssign x
|
Reg.Assign x -> goAssign x
|
||||||
Reg.Alloc x -> goAlloc x
|
Reg.Alloc x -> goAlloc x
|
||||||
Reg.AllocClosure x -> goAllocClosure x
|
Reg.AllocClosure x -> goAllocClosure x
|
||||||
|
Reg.Assert x -> goAssert x
|
||||||
Reg.Trace x -> goTrace x
|
Reg.Trace x -> goTrace x
|
||||||
Reg.Dump -> unsupported "dump"
|
Reg.Dump -> unsupported "dump"
|
||||||
Reg.Failure x -> goFail x
|
Reg.Failure x -> goFail x
|
||||||
@ -512,6 +513,18 @@ fromReg tab = mkResult $ run $ runLabelInfoBuilderWithNextId (Reg.getNextSymbolI
|
|||||||
storedArgsNum = length _instrAllocClosureArgs
|
storedArgsNum = length _instrAllocClosureArgs
|
||||||
leftArgsNum = _instrAllocClosureExpectedArgsNum - storedArgsNum
|
leftArgsNum = _instrAllocClosureExpectedArgsNum - storedArgsNum
|
||||||
|
|
||||||
|
goAssert :: Reg.InstrAssert -> Sem r ()
|
||||||
|
goAssert Reg.InstrAssert {..} = do
|
||||||
|
v <- goValue _instrAssertValue
|
||||||
|
case v of
|
||||||
|
Imm c
|
||||||
|
| c == 0 -> return ()
|
||||||
|
| otherwise ->
|
||||||
|
output' 0 $ mkAssign (MemRef Ap 0) (Binop $ BinopValue FieldAdd (MemRef Ap 0) (Imm 1))
|
||||||
|
Ref r ->
|
||||||
|
output' 0 $ Assert (InstrAssert r)
|
||||||
|
Lab {} -> unsupported "assert label"
|
||||||
|
|
||||||
goTrace :: Reg.InstrTrace -> Sem r ()
|
goTrace :: Reg.InstrTrace -> Sem r ()
|
||||||
goTrace Reg.InstrTrace {..} = do
|
goTrace Reg.InstrTrace {..} = do
|
||||||
v <- mkRValue _instrTraceValue
|
v <- mkRValue _instrTraceValue
|
||||||
|
@ -74,6 +74,7 @@ instruction =
|
|||||||
<|> parseJump
|
<|> parseJump
|
||||||
<|> parseCall
|
<|> parseCall
|
||||||
<|> parseReturn
|
<|> parseReturn
|
||||||
|
<|> parseAssert
|
||||||
<|> parseTrace
|
<|> parseTrace
|
||||||
<|> parseAssign
|
<|> parseAssign
|
||||||
|
|
||||||
@ -249,6 +250,12 @@ parseReturn = do
|
|||||||
kw kwRet
|
kw kwRet
|
||||||
return Return
|
return Return
|
||||||
|
|
||||||
|
parseAssert :: ParsecS r Instruction
|
||||||
|
parseAssert = do
|
||||||
|
kw kwAssert
|
||||||
|
r <- parseMemRef
|
||||||
|
return $ Assert $ InstrAssert {_instrAssertValue = r}
|
||||||
|
|
||||||
parseTrace :: (Member LabelInfoBuilder r) => ParsecS r Instruction
|
parseTrace :: (Member LabelInfoBuilder r) => ParsecS r Instruction
|
||||||
parseTrace = do
|
parseTrace = do
|
||||||
kw kwTrace
|
kw kwTrace
|
||||||
|
@ -18,6 +18,7 @@ validate labi instrs = mapM_ go instrs
|
|||||||
Call x -> goCall x
|
Call x -> goCall x
|
||||||
Return -> return ()
|
Return -> return ()
|
||||||
Alloc x -> goAlloc x
|
Alloc x -> goAlloc x
|
||||||
|
Assert x -> goAssert x
|
||||||
Trace x -> goTrace x
|
Trace x -> goTrace x
|
||||||
Hint {} -> return ()
|
Hint {} -> return ()
|
||||||
Label {} -> return ()
|
Label {} -> return ()
|
||||||
@ -66,3 +67,6 @@ validate labi instrs = mapM_ go instrs
|
|||||||
|
|
||||||
goTrace :: InstrTrace -> Either CasmError ()
|
goTrace :: InstrTrace -> Either CasmError ()
|
||||||
goTrace InstrTrace {..} = goRValue _instrTraceValue
|
goTrace InstrTrace {..} = goRValue _instrTraceValue
|
||||||
|
|
||||||
|
goAssert :: InstrAssert -> Either CasmError ()
|
||||||
|
goAssert InstrAssert {} = return ()
|
||||||
|
@ -125,7 +125,8 @@ instance Serialize BuiltinConstructor
|
|||||||
instance NFData BuiltinConstructor
|
instance NFData BuiltinConstructor
|
||||||
|
|
||||||
data BuiltinFunction
|
data BuiltinFunction
|
||||||
= BuiltinNatPlus
|
= BuiltinAssert
|
||||||
|
| BuiltinNatPlus
|
||||||
| BuiltinNatSub
|
| BuiltinNatSub
|
||||||
| BuiltinNatMul
|
| BuiltinNatMul
|
||||||
| BuiltinNatUDiv
|
| BuiltinNatUDiv
|
||||||
@ -163,6 +164,7 @@ instance NFData BuiltinFunction
|
|||||||
|
|
||||||
instance Pretty BuiltinFunction where
|
instance Pretty BuiltinFunction where
|
||||||
pretty = \case
|
pretty = \case
|
||||||
|
BuiltinAssert -> Str.assert
|
||||||
BuiltinNatPlus -> Str.natPlus
|
BuiltinNatPlus -> Str.natPlus
|
||||||
BuiltinNatSub -> Str.natSub
|
BuiltinNatSub -> Str.natSub
|
||||||
BuiltinNatMul -> Str.natMul
|
BuiltinNatMul -> Str.natMul
|
||||||
@ -368,6 +370,7 @@ isNatBuiltin = \case
|
|||||||
BuiltinNatLt -> True
|
BuiltinNatLt -> True
|
||||||
BuiltinNatEq -> True
|
BuiltinNatEq -> True
|
||||||
--
|
--
|
||||||
|
BuiltinAssert -> False
|
||||||
BuiltinBoolIf -> False
|
BuiltinBoolIf -> False
|
||||||
BuiltinBoolOr -> False
|
BuiltinBoolOr -> False
|
||||||
BuiltinBoolAnd -> False
|
BuiltinBoolAnd -> False
|
||||||
@ -403,6 +406,7 @@ isIntBuiltin = \case
|
|||||||
BuiltinIntLe -> True
|
BuiltinIntLe -> True
|
||||||
BuiltinIntLt -> True
|
BuiltinIntLt -> True
|
||||||
--
|
--
|
||||||
|
BuiltinAssert -> False
|
||||||
BuiltinNatPlus -> False
|
BuiltinNatPlus -> False
|
||||||
BuiltinNatSub -> False
|
BuiltinNatSub -> False
|
||||||
BuiltinNatMul -> False
|
BuiltinNatMul -> False
|
||||||
@ -425,6 +429,7 @@ isCastBuiltin = \case
|
|||||||
BuiltinFromNat -> True
|
BuiltinFromNat -> True
|
||||||
BuiltinFromInt -> True
|
BuiltinFromInt -> True
|
||||||
--
|
--
|
||||||
|
BuiltinAssert -> False
|
||||||
BuiltinIntEq -> False
|
BuiltinIntEq -> False
|
||||||
BuiltinIntPlus -> False
|
BuiltinIntPlus -> False
|
||||||
BuiltinIntSubNat -> False
|
BuiltinIntSubNat -> False
|
||||||
@ -496,6 +501,7 @@ isIgnoredBuiltin f
|
|||||||
-- Monad
|
-- Monad
|
||||||
BuiltinMonadBind -> False
|
BuiltinMonadBind -> False
|
||||||
-- Ignored
|
-- Ignored
|
||||||
|
BuiltinAssert -> True
|
||||||
BuiltinBoolIf -> True
|
BuiltinBoolIf -> True
|
||||||
BuiltinBoolOr -> True
|
BuiltinBoolOr -> True
|
||||||
BuiltinBoolAnd -> True
|
BuiltinBoolAnd -> True
|
||||||
|
@ -217,6 +217,7 @@ geval opts herr tab env0 = eval' env0
|
|||||||
OpSeq -> seqOp
|
OpSeq -> seqOp
|
||||||
OpFail -> failOp
|
OpFail -> failOp
|
||||||
OpTrace -> traceOp
|
OpTrace -> traceOp
|
||||||
|
OpAssert -> assertOp
|
||||||
OpAnomaGet -> anomaGetOp
|
OpAnomaGet -> anomaGetOp
|
||||||
OpAnomaEncode -> anomaEncodeOp
|
OpAnomaEncode -> anomaEncodeOp
|
||||||
OpAnomaDecode -> anomaDecodeOp
|
OpAnomaDecode -> anomaDecodeOp
|
||||||
@ -367,6 +368,21 @@ geval opts herr tab env0 = eval' env0
|
|||||||
unsafePerformIO (hPutStrLn herr (printNode v) >> return v)
|
unsafePerformIO (hPutStrLn herr (printNode v) >> return v)
|
||||||
{-# INLINE traceOp #-}
|
{-# INLINE traceOp #-}
|
||||||
|
|
||||||
|
assertOp :: [Node] -> Node
|
||||||
|
assertOp = unary $ \val ->
|
||||||
|
let !v = eval' env val
|
||||||
|
in if
|
||||||
|
| opts ^. evalOptionsSilent ->
|
||||||
|
v
|
||||||
|
| otherwise ->
|
||||||
|
case v of
|
||||||
|
NCtr Constr {..}
|
||||||
|
| _constrTag == BuiltinTag TagTrue ->
|
||||||
|
v
|
||||||
|
_ ->
|
||||||
|
Exception.throw (EvalError ("assertion failed: " <> printNode val) Nothing)
|
||||||
|
{-# INLINE assertOp #-}
|
||||||
|
|
||||||
anomaGetOp :: [Node] -> Node
|
anomaGetOp :: [Node] -> Node
|
||||||
anomaGetOp = unary $ \arg ->
|
anomaGetOp = unary $ \arg ->
|
||||||
if
|
if
|
||||||
|
@ -188,6 +188,7 @@ containsDebugOperations = ufold (\x xs -> x || or xs) isDebugOp
|
|||||||
OpTrace -> True
|
OpTrace -> True
|
||||||
OpFail -> True
|
OpFail -> True
|
||||||
OpSeq -> True
|
OpSeq -> True
|
||||||
|
OpAssert -> False
|
||||||
OpAnomaByteArrayFromAnomaContents -> False
|
OpAnomaByteArrayFromAnomaContents -> False
|
||||||
OpAnomaByteArrayToAnomaContents -> False
|
OpAnomaByteArrayToAnomaContents -> False
|
||||||
OpAnomaDecode -> False
|
OpAnomaDecode -> False
|
||||||
@ -466,6 +467,7 @@ builtinOpArgTypes = \case
|
|||||||
OpShow -> [mkDynamic']
|
OpShow -> [mkDynamic']
|
||||||
OpStrConcat -> [mkTypeString', mkTypeString']
|
OpStrConcat -> [mkTypeString', mkTypeString']
|
||||||
OpStrToInt -> [mkTypeString']
|
OpStrToInt -> [mkTypeString']
|
||||||
|
OpAssert -> [mkTypeBool']
|
||||||
OpSeq -> [mkDynamic', mkDynamic']
|
OpSeq -> [mkDynamic', mkDynamic']
|
||||||
OpTrace -> [mkDynamic']
|
OpTrace -> [mkDynamic']
|
||||||
OpFail -> [mkTypeString']
|
OpFail -> [mkTypeString']
|
||||||
|
@ -15,6 +15,7 @@ import Juvix.Data.Keyword.All
|
|||||||
kwAnomaVerifyDetached,
|
kwAnomaVerifyDetached,
|
||||||
kwAnomaVerifyWithMessage,
|
kwAnomaVerifyWithMessage,
|
||||||
kwAny,
|
kwAny,
|
||||||
|
kwAssert,
|
||||||
kwAssign,
|
kwAssign,
|
||||||
kwBindOperator,
|
kwBindOperator,
|
||||||
kwBottom,
|
kwBottom,
|
||||||
@ -72,6 +73,7 @@ allKeywordStrings = keywordsStrings allKeywords
|
|||||||
allKeywords :: [Keyword]
|
allKeywords :: [Keyword]
|
||||||
allKeywords =
|
allKeywords =
|
||||||
[ delimSemicolon,
|
[ delimSemicolon,
|
||||||
|
kwAssert,
|
||||||
kwAssign,
|
kwAssign,
|
||||||
kwBottom,
|
kwBottom,
|
||||||
kwBuiltin,
|
kwBuiltin,
|
||||||
|
@ -24,6 +24,7 @@ data BuiltinOp
|
|||||||
| OpStrConcat
|
| OpStrConcat
|
||||||
| OpStrToInt
|
| OpStrToInt
|
||||||
| OpSeq
|
| OpSeq
|
||||||
|
| OpAssert
|
||||||
| OpTrace
|
| OpTrace
|
||||||
| OpFail
|
| OpFail
|
||||||
| OpAnomaGet
|
| OpAnomaGet
|
||||||
@ -84,6 +85,7 @@ builtinOpArgsNum = \case
|
|||||||
OpStrConcat -> 2
|
OpStrConcat -> 2
|
||||||
OpStrToInt -> 1
|
OpStrToInt -> 1
|
||||||
OpSeq -> 2
|
OpSeq -> 2
|
||||||
|
OpAssert -> 1
|
||||||
OpTrace -> 1
|
OpTrace -> 1
|
||||||
OpFail -> 1
|
OpFail -> 1
|
||||||
OpAnomaGet -> 1
|
OpAnomaGet -> 1
|
||||||
@ -133,6 +135,7 @@ builtinIsFoldable = \case
|
|||||||
OpStrConcat -> True
|
OpStrConcat -> True
|
||||||
OpStrToInt -> True
|
OpStrToInt -> True
|
||||||
OpSeq -> False
|
OpSeq -> False
|
||||||
|
OpAssert -> False
|
||||||
OpTrace -> False
|
OpTrace -> False
|
||||||
OpFail -> False
|
OpFail -> False
|
||||||
OpAnomaGet -> False
|
OpAnomaGet -> False
|
||||||
|
@ -50,6 +50,7 @@ instance PrettyCode BuiltinOp where
|
|||||||
OpShow -> return primShow
|
OpShow -> return primShow
|
||||||
OpStrConcat -> return primStrConcat
|
OpStrConcat -> return primStrConcat
|
||||||
OpStrToInt -> return primStrToInt
|
OpStrToInt -> return primStrToInt
|
||||||
|
OpAssert -> return primAssert
|
||||||
OpSeq -> return primSeq
|
OpSeq -> return primSeq
|
||||||
OpTrace -> return primTrace
|
OpTrace -> return primTrace
|
||||||
OpFail -> return primFail
|
OpFail -> return primFail
|
||||||
@ -867,6 +868,9 @@ kwPi = keyword Str.piUnicode
|
|||||||
kwDef :: Doc Ann
|
kwDef :: Doc Ann
|
||||||
kwDef = keyword Str.def
|
kwDef = keyword Str.def
|
||||||
|
|
||||||
|
primAssert :: Doc Ann
|
||||||
|
primAssert = primitive Str.assert_
|
||||||
|
|
||||||
primSeq :: Doc Ann
|
primSeq :: Doc Ann
|
||||||
primSeq = primitive Str.seqq_
|
primSeq = primitive Str.seqq_
|
||||||
|
|
||||||
|
@ -64,6 +64,9 @@ computeNodeTypeInfo md = umapL go
|
|||||||
OpSeq -> case _builtinAppArgs of
|
OpSeq -> case _builtinAppArgs of
|
||||||
[_, arg2] -> Info.getNodeType arg2
|
[_, arg2] -> Info.getNodeType arg2
|
||||||
_ -> error "incorrect seq builtin application"
|
_ -> error "incorrect seq builtin application"
|
||||||
|
OpAssert -> case _builtinAppArgs of
|
||||||
|
[arg] -> Info.getNodeType arg
|
||||||
|
_ -> error "incorrect assert builtin application"
|
||||||
OpTrace -> case _builtinAppArgs of
|
OpTrace -> case _builtinAppArgs of
|
||||||
[arg] -> Info.getNodeType arg
|
[arg] -> Info.getNodeType arg
|
||||||
_ -> error "incorrect trace builtin application"
|
_ -> error "incorrect trace builtin application"
|
||||||
|
@ -1309,6 +1309,11 @@ goApplication a = do
|
|||||||
(_ : _ : arg1 : arg2 : xs) ->
|
(_ : _ : arg1 : arg2 : xs) ->
|
||||||
return (mkApps' (mkBuiltinApp' OpSeq [arg1, arg2]) xs)
|
return (mkApps' (mkBuiltinApp' OpSeq [arg1, arg2]) xs)
|
||||||
_ -> error "internal to core: seq must be called with 2 arguments"
|
_ -> error "internal to core: seq must be called with 2 arguments"
|
||||||
|
Just Internal.BuiltinAssert -> do
|
||||||
|
as <- exprArgs
|
||||||
|
case as of
|
||||||
|
(x : xs) -> return (mkApps' (mkBuiltinApp' OpAssert [x]) xs)
|
||||||
|
_ -> error "internal to core: assert must be called with 1 argument"
|
||||||
_ -> app
|
_ -> app
|
||||||
_ -> app
|
_ -> app
|
||||||
|
|
||||||
|
@ -569,6 +569,7 @@ builtinAppExpr varsNum vars = do
|
|||||||
<|> (kw kwShow $> OpShow)
|
<|> (kw kwShow $> OpShow)
|
||||||
<|> (kw kwStrConcat $> OpStrConcat)
|
<|> (kw kwStrConcat $> OpStrConcat)
|
||||||
<|> (kw kwStrToInt $> OpStrToInt)
|
<|> (kw kwStrToInt $> OpStrToInt)
|
||||||
|
<|> (kw kwAssert $> OpAssert)
|
||||||
<|> (kw kwSeqq $> OpSeq)
|
<|> (kw kwSeqq $> OpSeq)
|
||||||
<|> (kw kwTrace $> OpTrace)
|
<|> (kw kwTrace $> OpTrace)
|
||||||
<|> (kw kwFail $> OpFail)
|
<|> (kw kwFail $> OpFail)
|
||||||
|
@ -28,6 +28,7 @@ fromCore fsize tab =
|
|||||||
|
|
||||||
shouldKeepFunction :: BuiltinFunction -> Bool
|
shouldKeepFunction :: BuiltinFunction -> Bool
|
||||||
shouldKeepFunction = \case
|
shouldKeepFunction = \case
|
||||||
|
BuiltinAssert -> False
|
||||||
BuiltinNatPlus -> False
|
BuiltinNatPlus -> False
|
||||||
BuiltinNatSub -> False
|
BuiltinNatSub -> False
|
||||||
BuiltinNatMul -> False
|
BuiltinNatMul -> False
|
||||||
|
@ -14,6 +14,7 @@ import Data.HashSet qualified as HashSet
|
|||||||
import Data.IntMap.Strict qualified as IntMap
|
import Data.IntMap.Strict qualified as IntMap
|
||||||
import Data.List.NonEmpty qualified as NonEmpty
|
import Data.List.NonEmpty qualified as NonEmpty
|
||||||
import Juvix.Compiler.Builtins
|
import Juvix.Compiler.Builtins
|
||||||
|
import Juvix.Compiler.Builtins.Assert
|
||||||
import Juvix.Compiler.Builtins.Pair
|
import Juvix.Compiler.Builtins.Pair
|
||||||
import Juvix.Compiler.Concrete.Data.ScopedName qualified as S
|
import Juvix.Compiler.Concrete.Data.ScopedName qualified as S
|
||||||
import Juvix.Compiler.Concrete.Extra qualified as Concrete
|
import Juvix.Compiler.Concrete.Extra qualified as Concrete
|
||||||
@ -537,6 +538,7 @@ checkBuiltinFunction ::
|
|||||||
BuiltinFunction ->
|
BuiltinFunction ->
|
||||||
Sem r ()
|
Sem r ()
|
||||||
checkBuiltinFunction d f = localBuiltins $ case f of
|
checkBuiltinFunction d f = localBuiltins $ case f of
|
||||||
|
BuiltinAssert -> checkAssert d
|
||||||
BuiltinNatPlus -> checkNatPlus d
|
BuiltinNatPlus -> checkNatPlus d
|
||||||
BuiltinNatSub -> checkNatSub d
|
BuiltinNatSub -> checkNatSub d
|
||||||
BuiltinNatMul -> checkNatMul d
|
BuiltinNatMul -> checkNatMul d
|
||||||
|
@ -517,6 +517,9 @@ compile = \case
|
|||||||
arg <- compile _nodeUnopArg
|
arg <- compile _nodeUnopArg
|
||||||
case _nodeUnopOpcode of
|
case _nodeUnopOpcode of
|
||||||
Tree.PrimUnop op -> return $ goPrimUnop op arg
|
Tree.PrimUnop op -> return $ goPrimUnop op arg
|
||||||
|
Tree.OpAssert ->
|
||||||
|
-- TODO: remove duplication of `arg` here
|
||||||
|
return (branch arg arg crash)
|
||||||
Tree.OpFail -> return crash
|
Tree.OpFail -> return crash
|
||||||
Tree.OpTrace -> goTrace arg
|
Tree.OpTrace -> goTrace arg
|
||||||
|
|
||||||
@ -525,6 +528,7 @@ compile = \case
|
|||||||
Tree.OpShow -> stringsErr "show"
|
Tree.OpShow -> stringsErr "show"
|
||||||
Tree.OpStrToInt -> stringsErr "strToInt"
|
Tree.OpStrToInt -> stringsErr "strToInt"
|
||||||
Tree.OpArgsNum ->
|
Tree.OpArgsNum ->
|
||||||
|
-- TODO: remove duplication of `arg` here!!!
|
||||||
let getF f = getClosureField f arg
|
let getF f = getClosureField f arg
|
||||||
in sub (getF ClosureTotalArgsNum) (getF ClosureArgsNum)
|
in sub (getF ClosureTotalArgsNum) (getF ClosureArgsNum)
|
||||||
Tree.OpIntToField -> fieldErr
|
Tree.OpIntToField -> fieldErr
|
||||||
@ -651,6 +655,7 @@ compile = \case
|
|||||||
enabled <- asks (^. compilerOptions . compilerOptionsEnableTrace)
|
enabled <- asks (^. compilerOptions . compilerOptionsEnableTrace)
|
||||||
return $
|
return $
|
||||||
if
|
if
|
||||||
|
-- TODO: remove duplication of `arg` here
|
||||||
| enabled -> OpTrace # arg # arg
|
| enabled -> OpTrace # arg # arg
|
||||||
| otherwise -> arg
|
| otherwise -> arg
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ overValueRefs'' f = \case
|
|||||||
If x -> If <$> goIf x
|
If x -> If <$> goIf x
|
||||||
Branch x -> Branch <$> goBranch x
|
Branch x -> Branch <$> goBranch x
|
||||||
Case x -> Case <$> goCase x
|
Case x -> Case <$> goCase x
|
||||||
|
Assert x -> Assert <$> goAssert x
|
||||||
Trace x -> Trace <$> goTrace x
|
Trace x -> Trace <$> goTrace x
|
||||||
Dump -> return Dump
|
Dump -> return Dump
|
||||||
Failure x -> Failure <$> goFailure x
|
Failure x -> Failure <$> goFailure x
|
||||||
@ -174,6 +175,9 @@ overValueRefs'' f = \case
|
|||||||
goCase :: InstrCase -> m InstrCase
|
goCase :: InstrCase -> m InstrCase
|
||||||
goCase = overM instrCaseValue goValue
|
goCase = overM instrCaseValue goValue
|
||||||
|
|
||||||
|
goAssert :: InstrAssert -> m InstrAssert
|
||||||
|
goAssert = overM instrAssertValue goValue
|
||||||
|
|
||||||
goTrace :: InstrTrace -> m InstrTrace
|
goTrace :: InstrTrace -> m InstrTrace
|
||||||
goTrace = overM instrTraceValue goValue
|
goTrace = overM instrTraceValue goValue
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ getValueRefs = \case
|
|||||||
Assign x -> goAssign x
|
Assign x -> goAssign x
|
||||||
Alloc x -> goAlloc x
|
Alloc x -> goAlloc x
|
||||||
AllocClosure x -> goAllocClosure x
|
AllocClosure x -> goAllocClosure x
|
||||||
|
Assert x -> goAssert x
|
||||||
Trace x -> goTrace x
|
Trace x -> goTrace x
|
||||||
Dump -> []
|
Dump -> []
|
||||||
Failure x -> goFailure x
|
Failure x -> goFailure x
|
||||||
@ -103,6 +104,9 @@ getValueRefs = \case
|
|||||||
goAllocClosure :: InstrAllocClosure -> [VarRef]
|
goAllocClosure :: InstrAllocClosure -> [VarRef]
|
||||||
goAllocClosure InstrAllocClosure {..} = concatMap getValueRefs'' _instrAllocClosureArgs
|
goAllocClosure InstrAllocClosure {..} = concatMap getValueRefs'' _instrAllocClosureArgs
|
||||||
|
|
||||||
|
goAssert :: InstrAssert -> [VarRef]
|
||||||
|
goAssert InstrAssert {..} = getValueRefs'' _instrAssertValue
|
||||||
|
|
||||||
goTrace :: InstrTrace -> [VarRef]
|
goTrace :: InstrTrace -> [VarRef]
|
||||||
goTrace InstrTrace {..} = getValueRefs'' _instrTraceValue
|
goTrace InstrTrace {..} = getValueRefs'' _instrTraceValue
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ computeMaxStackHeight lims = maximum . map go
|
|||||||
Unop {} -> 0
|
Unop {} -> 0
|
||||||
Cairo {} -> 0
|
Cairo {} -> 0
|
||||||
Assign {} -> 0
|
Assign {} -> 0
|
||||||
|
Assert {} -> 0
|
||||||
Trace {} -> 0
|
Trace {} -> 0
|
||||||
Dump -> 0
|
Dump -> 0
|
||||||
Failure {} -> 0
|
Failure {} -> 0
|
||||||
@ -73,6 +74,7 @@ computeMaxCallClosuresArgsNum = maximum . map go
|
|||||||
Unop {} -> 0
|
Unop {} -> 0
|
||||||
Cairo {} -> 0
|
Cairo {} -> 0
|
||||||
Assign {} -> 0
|
Assign {} -> 0
|
||||||
|
Assert {} -> 0
|
||||||
Trace {} -> 0
|
Trace {} -> 0
|
||||||
Dump -> 0
|
Dump -> 0
|
||||||
Failure {} -> 0
|
Failure {} -> 0
|
||||||
@ -121,6 +123,8 @@ computeStringMap strs = snd . run . execState (HashMap.size strs, strs) . mapM g
|
|||||||
mapM_ goVal _instrCairoArgs
|
mapM_ goVal _instrCairoArgs
|
||||||
Assign InstrAssign {..} ->
|
Assign InstrAssign {..} ->
|
||||||
goVal _instrAssignValue
|
goVal _instrAssignValue
|
||||||
|
Assert InstrAssert {..} ->
|
||||||
|
goVal _instrAssertValue
|
||||||
Trace InstrTrace {..} ->
|
Trace InstrTrace {..} ->
|
||||||
goVal _instrTraceValue
|
goVal _instrTraceValue
|
||||||
Dump -> return ()
|
Dump -> return ()
|
||||||
@ -180,6 +184,7 @@ computeLocalVarsNum = maximum . map go
|
|||||||
Unop InstrUnop {..} -> goVarRef _instrUnopResult
|
Unop InstrUnop {..} -> goVarRef _instrUnopResult
|
||||||
Cairo InstrCairo {..} -> goVarRef _instrCairoResult
|
Cairo InstrCairo {..} -> goVarRef _instrCairoResult
|
||||||
Assign InstrAssign {..} -> goVarRef _instrAssignResult
|
Assign InstrAssign {..} -> goVarRef _instrAssignResult
|
||||||
|
Assert {} -> 0
|
||||||
Trace {} -> 0
|
Trace {} -> 0
|
||||||
Dump -> 0
|
Dump -> 0
|
||||||
Failure {} -> 0
|
Failure {} -> 0
|
||||||
|
@ -48,6 +48,7 @@ runFunction hout infoTable args0 info0 = do
|
|||||||
Unop x -> goUnop args tmps instrs x
|
Unop x -> goUnop args tmps instrs x
|
||||||
Cairo {} -> throwRunError "unsupported: Cairo builtin" Nothing
|
Cairo {} -> throwRunError "unsupported: Cairo builtin" Nothing
|
||||||
Assign x -> goAssign args tmps instrs x
|
Assign x -> goAssign args tmps instrs x
|
||||||
|
Assert x -> goAssert args tmps instrs x
|
||||||
Trace x -> goTrace args tmps instrs x
|
Trace x -> goTrace args tmps instrs x
|
||||||
Dump -> goDump args tmps instrs
|
Dump -> goDump args tmps instrs
|
||||||
Failure x -> goFailure args tmps instrs x
|
Failure x -> goFailure args tmps instrs x
|
||||||
@ -130,6 +131,15 @@ runFunction hout infoTable args0 info0 = do
|
|||||||
writeVarRef args tmps _instrAssignResult val
|
writeVarRef args tmps _instrAssignResult val
|
||||||
go args tmps instrs
|
go args tmps instrs
|
||||||
|
|
||||||
|
goAssert :: Args -> Vars s -> Code -> InstrAssert -> ST s Val
|
||||||
|
goAssert args tmps instrs InstrAssert {..} = do
|
||||||
|
val <- readValue args tmps _instrAssertValue
|
||||||
|
case val of
|
||||||
|
ValBool True ->
|
||||||
|
go args tmps instrs
|
||||||
|
_ ->
|
||||||
|
throwRunError "assertion failed" Nothing
|
||||||
|
|
||||||
goTrace :: Args -> Vars s -> Code -> InstrTrace -> ST s Val
|
goTrace :: Args -> Vars s -> Code -> InstrTrace -> ST s Val
|
||||||
goTrace args tmps instrs InstrTrace {..} = do
|
goTrace args tmps instrs InstrTrace {..} = do
|
||||||
val <- readValue args tmps _instrTraceValue
|
val <- readValue args tmps _instrTraceValue
|
||||||
|
@ -10,6 +10,7 @@ import Juvix.Data.Keyword.All
|
|||||||
( kwAdd_,
|
( kwAdd_,
|
||||||
kwAlloc,
|
kwAlloc,
|
||||||
kwArgsNum,
|
kwArgsNum,
|
||||||
|
kwAssert,
|
||||||
kwAtoi,
|
kwAtoi,
|
||||||
kwBr,
|
kwBr,
|
||||||
kwCAlloc,
|
kwCAlloc,
|
||||||
@ -74,6 +75,7 @@ allKeywords =
|
|||||||
kwIf,
|
kwIf,
|
||||||
kwShow,
|
kwShow,
|
||||||
kwAtoi,
|
kwAtoi,
|
||||||
|
kwAssert,
|
||||||
kwTrace,
|
kwTrace,
|
||||||
kwDump,
|
kwDump,
|
||||||
kwPrealloc,
|
kwPrealloc,
|
||||||
|
@ -25,7 +25,8 @@ data Instruction
|
|||||||
| Branch InstrBranch
|
| Branch InstrBranch
|
||||||
| Case InstrCase
|
| Case InstrCase
|
||||||
| ----
|
| ----
|
||||||
Trace InstrTrace
|
Assert InstrAssert
|
||||||
|
| Trace InstrTrace
|
||||||
| Dump
|
| Dump
|
||||||
| Failure InstrFailure
|
| Failure InstrFailure
|
||||||
| Prealloc InstrPrealloc
|
| Prealloc InstrPrealloc
|
||||||
|
@ -20,6 +20,7 @@ data Instruction
|
|||||||
| Assign InstrAssign
|
| Assign InstrAssign
|
||||||
| Alloc InstrAlloc
|
| Alloc InstrAlloc
|
||||||
| AllocClosure InstrAllocClosure
|
| AllocClosure InstrAllocClosure
|
||||||
|
| Assert InstrAssert
|
||||||
| Trace InstrTrace
|
| Trace InstrTrace
|
||||||
| Dump
|
| Dump
|
||||||
| Failure InstrFailure
|
| Failure InstrFailure
|
||||||
|
@ -80,6 +80,11 @@ data InstrAssign = InstrAssign
|
|||||||
}
|
}
|
||||||
deriving stock (Eq)
|
deriving stock (Eq)
|
||||||
|
|
||||||
|
newtype InstrAssert = InstrAssert
|
||||||
|
{ _instrAssertValue :: Value
|
||||||
|
}
|
||||||
|
deriving stock (Eq)
|
||||||
|
|
||||||
newtype InstrTrace = InstrTrace
|
newtype InstrTrace = InstrTrace
|
||||||
{ _instrTraceValue :: Value
|
{ _instrTraceValue :: Value
|
||||||
}
|
}
|
||||||
@ -184,6 +189,7 @@ makeLenses ''InstrBinop
|
|||||||
makeLenses ''InstrUnop
|
makeLenses ''InstrUnop
|
||||||
makeLenses ''InstrCairo
|
makeLenses ''InstrCairo
|
||||||
makeLenses ''InstrAssign
|
makeLenses ''InstrAssign
|
||||||
|
makeLenses ''InstrAssert
|
||||||
makeLenses ''InstrTrace
|
makeLenses ''InstrTrace
|
||||||
makeLenses ''InstrFailure
|
makeLenses ''InstrFailure
|
||||||
makeLenses ''InstrAlloc
|
makeLenses ''InstrAlloc
|
||||||
|
@ -75,6 +75,11 @@ instance PrettyCode InstrAssign where
|
|||||||
val <- ppCode _instrAssignValue
|
val <- ppCode _instrAssignValue
|
||||||
return $ res <+> primitive Str.equal <+> val
|
return $ res <+> primitive Str.equal <+> val
|
||||||
|
|
||||||
|
instance PrettyCode InstrAssert where
|
||||||
|
ppCode InstrAssert {..} = do
|
||||||
|
val <- ppCode _instrAssertValue
|
||||||
|
return $ primitive Str.assert_ <+> val
|
||||||
|
|
||||||
instance PrettyCode InstrTrace where
|
instance PrettyCode InstrTrace where
|
||||||
ppCode InstrTrace {..} = do
|
ppCode InstrTrace {..} = do
|
||||||
val <- ppCode _instrTraceValue
|
val <- ppCode _instrTraceValue
|
||||||
@ -271,6 +276,7 @@ instance PrettyCode Instruction where
|
|||||||
Unop x -> ppCode x
|
Unop x -> ppCode x
|
||||||
Cairo x -> ppCode x
|
Cairo x -> ppCode x
|
||||||
Assign x -> ppCode x
|
Assign x -> ppCode x
|
||||||
|
Assert x -> ppCode x
|
||||||
Trace x -> ppCode x
|
Trace x -> ppCode x
|
||||||
Dump -> return $ primitive Str.dump
|
Dump -> return $ primitive Str.dump
|
||||||
Failure x -> ppCode x
|
Failure x -> ppCode x
|
||||||
|
@ -30,6 +30,7 @@ fromReg = over infoFunctions (fmap (over functionCode goCode))
|
|||||||
Reg.Case x -> mkBlock (Case (fmap goCode x))
|
Reg.Case x -> mkBlock (Case (fmap goCode x))
|
||||||
Reg.CallClosures {} -> impossible
|
Reg.CallClosures {} -> impossible
|
||||||
Reg.TailCallClosures {} -> impossible
|
Reg.TailCallClosures {} -> impossible
|
||||||
|
Reg.Assert x -> over blockBody (Assert x :) (goCode is)
|
||||||
Reg.Trace x -> over blockBody (Trace x :) (goCode is)
|
Reg.Trace x -> over blockBody (Trace x :) (goCode is)
|
||||||
Reg.Dump -> over blockBody (Dump :) (goCode is)
|
Reg.Dump -> over blockBody (Dump :) (goCode is)
|
||||||
Reg.Failure x -> over blockBody (Failure x :) (goCode is)
|
Reg.Failure x -> over blockBody (Failure x :) (goCode is)
|
||||||
|
@ -69,6 +69,7 @@ fromAsmInstr funInfo tab si Asm.CmdInstr {..} =
|
|||||||
Asm.Cairo op -> return $ mkCairo op
|
Asm.Cairo op -> return $ mkCairo op
|
||||||
Asm.Push val -> return $ mkAssign (mkVarRef VarGroupLocal (ntmps + n + 1)) (mkValue val)
|
Asm.Push val -> return $ mkAssign (mkVarRef VarGroupLocal (ntmps + n + 1)) (mkValue val)
|
||||||
Asm.Pop -> return Nop
|
Asm.Pop -> return Nop
|
||||||
|
Asm.Assert -> return $ Assert $ InstrAssert (VRef $ mkVarRef VarGroupLocal (ntmps + n))
|
||||||
Asm.Trace -> return $ Trace $ InstrTrace (VRef $ mkVarRef VarGroupLocal (ntmps + n))
|
Asm.Trace -> return $ Trace $ InstrTrace (VRef $ mkVarRef VarGroupLocal (ntmps + n))
|
||||||
Asm.Dump -> return Dump
|
Asm.Dump -> return Dump
|
||||||
Asm.Failure -> return $ Failure $ InstrFailure (VRef $ mkVarRef VarGroupLocal (ntmps + n))
|
Asm.Failure -> return $ Failure $ InstrFailure (VRef $ mkVarRef VarGroupLocal (ntmps + n))
|
||||||
|
@ -53,6 +53,7 @@ instruction ::
|
|||||||
ParsecS r Instruction
|
ParsecS r Instruction
|
||||||
instruction =
|
instruction =
|
||||||
(instrNop >> return Nop)
|
(instrNop >> return Nop)
|
||||||
|
<|> (Assert <$> instrAssert)
|
||||||
<|> (Trace <$> instrTrace)
|
<|> (Trace <$> instrTrace)
|
||||||
<|> (instrDump >> return Dump)
|
<|> (instrDump >> return Dump)
|
||||||
<|> (Failure <$> instrFailure)
|
<|> (Failure <$> instrFailure)
|
||||||
@ -195,6 +196,17 @@ instrTrace = do
|
|||||||
{ _instrTraceValue = val
|
{ _instrTraceValue = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instrAssert ::
|
||||||
|
(Members '[Reader ParserSig, InfoTableBuilder, State LocalParams] r) =>
|
||||||
|
ParsecS r InstrAssert
|
||||||
|
instrAssert = do
|
||||||
|
kw kwAssert
|
||||||
|
val <- value
|
||||||
|
return
|
||||||
|
InstrAssert
|
||||||
|
{ _instrAssertValue = val
|
||||||
|
}
|
||||||
|
|
||||||
instrDump :: ParsecS r ()
|
instrDump :: ParsecS r ()
|
||||||
instrDump = kw kwDump
|
instrDump = kw kwDump
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ hEval hout tab = eval' [] mempty
|
|||||||
let !v = eval' args temps _nodeUnopArg
|
let !v = eval' args temps _nodeUnopArg
|
||||||
in case _nodeUnopOpcode of
|
in case _nodeUnopOpcode of
|
||||||
PrimUnop op -> eitherToError $ evalUnop tab op v
|
PrimUnop op -> eitherToError $ evalUnop tab op v
|
||||||
|
OpAssert -> goAssert v
|
||||||
OpTrace -> goTrace v
|
OpTrace -> goTrace v
|
||||||
OpFail -> goFail v
|
OpFail -> goFail v
|
||||||
|
|
||||||
@ -105,6 +106,11 @@ hEval hout tab = eval' [] mempty
|
|||||||
_ -> evalError "expected either a nullary or a binary constructor"
|
_ -> evalError "expected either a nullary or a binary constructor"
|
||||||
_ -> evalError "expected a constructor"
|
_ -> evalError "expected a constructor"
|
||||||
|
|
||||||
|
goAssert :: Value -> Value
|
||||||
|
goAssert = \case
|
||||||
|
ValBool True -> ValBool True
|
||||||
|
_ -> evalError "assertion failed"
|
||||||
|
|
||||||
goFail :: Value -> Value
|
goFail :: Value -> Value
|
||||||
goFail v = evalError ("failure: " <> printValue tab v)
|
goFail v = evalError ("failure: " <> printValue tab v)
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ eval tab = runReader emptyEvalCtx . eval'
|
|||||||
v <- eval' _nodeUnopArg
|
v <- eval' _nodeUnopArg
|
||||||
case _nodeUnopOpcode of
|
case _nodeUnopOpcode of
|
||||||
PrimUnop op -> eitherToError $ evalUnop tab op v
|
PrimUnop op -> eitherToError $ evalUnop tab op v
|
||||||
|
OpAssert -> goAssert v
|
||||||
OpTrace -> goTrace v
|
OpTrace -> goTrace v
|
||||||
OpFail -> goFail v
|
OpFail -> goFail v
|
||||||
|
|
||||||
@ -100,6 +101,12 @@ eval tab = runReader emptyEvalCtx . eval'
|
|||||||
_ -> evalError "expected either a nullary or a binary constructor"
|
_ -> evalError "expected either a nullary or a binary constructor"
|
||||||
_ -> evalError "expected a constructor"
|
_ -> evalError "expected a constructor"
|
||||||
|
|
||||||
|
goAssert :: Value -> Sem r' Value
|
||||||
|
goAssert = \case
|
||||||
|
ValBool True -> return $ ValBool True
|
||||||
|
ValBool False -> evalError "assertion failed"
|
||||||
|
v -> evalError ("expected a boolean: " <> printValue tab v)
|
||||||
|
|
||||||
goFail :: Value -> Sem r' Value
|
goFail :: Value -> Sem r' Value
|
||||||
goFail v = evalError ("failure: " <> printValue tab v)
|
goFail v = evalError ("failure: " <> printValue tab v)
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import Juvix.Data.Keyword.All
|
|||||||
kwAnomaVerifyDetached,
|
kwAnomaVerifyDetached,
|
||||||
kwAnomaVerifyWithMessage,
|
kwAnomaVerifyWithMessage,
|
||||||
kwArgsNum,
|
kwArgsNum,
|
||||||
|
kwAssert,
|
||||||
kwAtoi,
|
kwAtoi,
|
||||||
kwBr,
|
kwBr,
|
||||||
kwByteArrayFromListUInt8,
|
kwByteArrayFromListUInt8,
|
||||||
@ -70,6 +71,7 @@ allKeywords =
|
|||||||
kwStrcat,
|
kwStrcat,
|
||||||
kwShow,
|
kwShow,
|
||||||
kwAtoi,
|
kwAtoi,
|
||||||
|
kwAssert,
|
||||||
kwTrace,
|
kwTrace,
|
||||||
kwFail,
|
kwFail,
|
||||||
kwArgsNum,
|
kwArgsNum,
|
||||||
|
@ -65,6 +65,8 @@ data BinaryOpcode
|
|||||||
|
|
||||||
data UnaryOpcode
|
data UnaryOpcode
|
||||||
= PrimUnop UnaryOp
|
= PrimUnop UnaryOp
|
||||||
|
| -- | Assert a boolean and return it
|
||||||
|
OpAssert
|
||||||
| -- | Print a debug log of the argument and return it.
|
| -- | Print a debug log of the argument and return it.
|
||||||
OpTrace
|
OpTrace
|
||||||
| -- | Interrupt execution with a runtime error printing the argument.
|
| -- | Interrupt execution with a runtime error printing the argument.
|
||||||
|
@ -297,6 +297,7 @@ instance PrettyCode AnomaOp where
|
|||||||
instance PrettyCode UnaryOpcode where
|
instance PrettyCode UnaryOpcode where
|
||||||
ppCode = \case
|
ppCode = \case
|
||||||
PrimUnop x -> ppCode x
|
PrimUnop x -> ppCode x
|
||||||
|
OpAssert -> return $ primitive Str.instrAssert
|
||||||
OpTrace -> return $ primitive Str.instrTrace
|
OpTrace -> return $ primitive Str.instrTrace
|
||||||
OpFail -> return $ primitive Str.instrFailure
|
OpFail -> return $ primitive Str.instrFailure
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ inferType tab funInfo = goInfer mempty
|
|||||||
goUnop :: BinderList Type -> NodeUnop -> Sem r Type
|
goUnop :: BinderList Type -> NodeUnop -> Sem r Type
|
||||||
goUnop bl NodeUnop {..} = case _nodeUnopOpcode of
|
goUnop bl NodeUnop {..} = case _nodeUnopOpcode of
|
||||||
PrimUnop x -> checkPrimUnop x
|
PrimUnop x -> checkPrimUnop x
|
||||||
|
OpAssert -> goInfer bl _nodeUnopArg
|
||||||
OpTrace -> goInfer bl _nodeUnopArg
|
OpTrace -> goInfer bl _nodeUnopArg
|
||||||
OpFail -> checkUnop TyDynamic TyDynamic
|
OpFail -> checkUnop TyDynamic TyDynamic
|
||||||
where
|
where
|
||||||
|
@ -92,6 +92,7 @@ goFunction infoTab fi = do
|
|||||||
Asm.Push (Asm.Constant c) -> return (mkConst c)
|
Asm.Push (Asm.Constant c) -> return (mkConst c)
|
||||||
Asm.Push (Asm.Ref r) -> return (mkMemRef r)
|
Asm.Push (Asm.Ref r) -> return (mkMemRef r)
|
||||||
Asm.Pop -> goPop
|
Asm.Pop -> goPop
|
||||||
|
Asm.Assert -> goAssert
|
||||||
Asm.Trace -> goTrace
|
Asm.Trace -> goTrace
|
||||||
Asm.Dump -> unsupported (_cmdInstrInfo ^. Asm.commandInfoLocation)
|
Asm.Dump -> unsupported (_cmdInstrInfo ^. Asm.commandInfoLocation)
|
||||||
Asm.Failure -> goUnop OpFail
|
Asm.Failure -> goUnop OpFail
|
||||||
@ -244,8 +245,8 @@ goFunction infoTab fi = do
|
|||||||
_nodeBinopArg2 = arg2
|
_nodeBinopArg2 = arg2
|
||||||
}
|
}
|
||||||
|
|
||||||
goTrace :: Sem r Node
|
goSeqOp :: UnaryOpcode -> Sem r Node
|
||||||
goTrace = do
|
goSeqOp op = do
|
||||||
arg <- goCode
|
arg <- goCode
|
||||||
off <- asks (^. tempSize)
|
off <- asks (^. tempSize)
|
||||||
let ref = mkMemRef $ DRef $ mkTempRef $ OffsetRef off Nothing
|
let ref = mkMemRef $ DRef $ mkTempRef $ OffsetRef off Nothing
|
||||||
@ -264,13 +265,19 @@ goFunction infoTab fi = do
|
|||||||
Unop
|
Unop
|
||||||
NodeUnop
|
NodeUnop
|
||||||
{ _nodeUnopInfo = mempty,
|
{ _nodeUnopInfo = mempty,
|
||||||
_nodeUnopOpcode = OpTrace,
|
_nodeUnopOpcode = op,
|
||||||
_nodeUnopArg = ref
|
_nodeUnopArg = ref
|
||||||
},
|
},
|
||||||
_nodeBinopArg2 = ref
|
_nodeBinopArg2 = ref
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goAssert :: Sem r Node
|
||||||
|
goAssert = goSeqOp OpAssert
|
||||||
|
|
||||||
|
goTrace :: Sem r Node
|
||||||
|
goTrace = goSeqOp OpTrace
|
||||||
|
|
||||||
goArgs :: Int -> Sem r [Node]
|
goArgs :: Int -> Sem r [Node]
|
||||||
goArgs n = mapM (const goCode) [1 .. n]
|
goArgs n = mapM (const goCode) [1 .. n]
|
||||||
|
|
||||||
|
@ -163,6 +163,16 @@ genCode infoTable fi =
|
|||||||
_nodeAnomaOpcode = genAnomaOp _builtinAppOp,
|
_nodeAnomaOpcode = genAnomaOp _builtinAppOp,
|
||||||
_nodeAnomaArgs = args
|
_nodeAnomaArgs = args
|
||||||
}
|
}
|
||||||
|
| _builtinAppOp == Core.OpAssert =
|
||||||
|
case args of
|
||||||
|
[arg] ->
|
||||||
|
Unop $
|
||||||
|
NodeUnop
|
||||||
|
{ _nodeUnopInfo = mempty,
|
||||||
|
_nodeUnopOpcode = OpAssert,
|
||||||
|
_nodeUnopArg = arg
|
||||||
|
}
|
||||||
|
_ -> impossible
|
||||||
| otherwise =
|
| otherwise =
|
||||||
case args of
|
case args of
|
||||||
[arg] ->
|
[arg] ->
|
||||||
|
@ -106,6 +106,7 @@ parseUnop ::
|
|||||||
parseUnop =
|
parseUnop =
|
||||||
parseUnaryOp kwShow (PrimUnop OpShow)
|
parseUnaryOp kwShow (PrimUnop OpShow)
|
||||||
<|> parseUnaryOp kwAtoi (PrimUnop OpStrToInt)
|
<|> parseUnaryOp kwAtoi (PrimUnop OpStrToInt)
|
||||||
|
<|> parseUnaryOp kwAssert OpAssert
|
||||||
<|> parseUnaryOp kwTrace OpTrace
|
<|> parseUnaryOp kwTrace OpTrace
|
||||||
<|> parseUnaryOp kwFail OpFail
|
<|> parseUnaryOp kwFail OpFail
|
||||||
<|> parseUnaryOp kwArgsNum (PrimUnop OpArgsNum)
|
<|> parseUnaryOp kwArgsNum (PrimUnop OpArgsNum)
|
||||||
|
@ -265,6 +265,9 @@ kwSeqq = asciiKw Str.seqq_
|
|||||||
kwSSeq :: Keyword
|
kwSSeq :: Keyword
|
||||||
kwSSeq = asciiKw Str.sseq_
|
kwSSeq = asciiKw Str.sseq_
|
||||||
|
|
||||||
|
kwAssert :: Keyword
|
||||||
|
kwAssert = asciiKw Str.assert_
|
||||||
|
|
||||||
kwTrace :: Keyword
|
kwTrace :: Keyword
|
||||||
kwTrace = asciiKw Str.trace_
|
kwTrace = asciiKw Str.trace_
|
||||||
|
|
||||||
|
@ -260,6 +260,9 @@ ioSequence = "IO-sequence"
|
|||||||
ioReadline :: (IsString s) => s
|
ioReadline :: (IsString s) => s
|
||||||
ioReadline = "IO-readline"
|
ioReadline = "IO-readline"
|
||||||
|
|
||||||
|
assert :: (IsString s) => s
|
||||||
|
assert = "assert"
|
||||||
|
|
||||||
natPrint :: (IsString s) => s
|
natPrint :: (IsString s) => s
|
||||||
natPrint = "nat-print"
|
natPrint = "nat-print"
|
||||||
|
|
||||||
@ -482,6 +485,9 @@ sseq_ = "seq"
|
|||||||
eq :: (IsString s) => s
|
eq :: (IsString s) => s
|
||||||
eq = "eq"
|
eq = "eq"
|
||||||
|
|
||||||
|
assert_ :: (IsString s) => s
|
||||||
|
assert_ = "assert"
|
||||||
|
|
||||||
trace_ :: (IsString s) => s
|
trace_ :: (IsString s) => s
|
||||||
trace_ = "trace"
|
trace_ = "trace"
|
||||||
|
|
||||||
@ -845,6 +851,9 @@ instrPusht = "pusht"
|
|||||||
instrPopt :: (IsString s) => s
|
instrPopt :: (IsString s) => s
|
||||||
instrPopt = "popt"
|
instrPopt = "popt"
|
||||||
|
|
||||||
|
instrAssert :: (IsString s) => s
|
||||||
|
instrAssert = "assert"
|
||||||
|
|
||||||
instrTrace :: (IsString s) => s
|
instrTrace :: (IsString s) => s
|
||||||
instrTrace = "trace"
|
instrTrace = "trace"
|
||||||
|
|
||||||
|
@ -557,5 +557,13 @@ tests =
|
|||||||
$(mkRelDir ".")
|
$(mkRelDir ".")
|
||||||
$(mkRelFile "test077.juvix")
|
$(mkRelFile "test077.juvix")
|
||||||
(Just $(mkRelFile "in/test077.json"))
|
(Just $(mkRelFile "in/test077.json"))
|
||||||
$(mkRelFile "out/test077.out")
|
$(mkRelFile "out/test077.out"),
|
||||||
|
posTest
|
||||||
|
"Test078: Assertions"
|
||||||
|
True
|
||||||
|
True
|
||||||
|
$(mkRelDir ".")
|
||||||
|
$(mkRelFile "test078.juvix")
|
||||||
|
Nothing
|
||||||
|
$(mkRelFile "out/test078.out")
|
||||||
]
|
]
|
||||||
|
@ -178,5 +178,13 @@ tests =
|
|||||||
$(mkRelDir ".")
|
$(mkRelDir ".")
|
||||||
$(mkRelFile "test017.casm")
|
$(mkRelFile "test017.casm")
|
||||||
$(mkRelFile "out/test017.out")
|
$(mkRelFile "out/test017.out")
|
||||||
|
Nothing,
|
||||||
|
PosTest
|
||||||
|
"Test018: Assertions"
|
||||||
|
True
|
||||||
|
True
|
||||||
|
$(mkRelDir ".")
|
||||||
|
$(mkRelFile "test018.casm")
|
||||||
|
$(mkRelFile "out/test018.out")
|
||||||
Nothing
|
Nothing
|
||||||
]
|
]
|
||||||
|
1
tests/Casm/Compilation/positive/out/test078.out
Normal file
1
tests/Casm/Compilation/positive/out/test078.out
Normal file
@ -0,0 +1 @@
|
|||||||
|
482630520
|
@ -40,11 +40,3 @@ main
|
|||||||
| else := Resource.fld0 input;
|
| else := Resource.fld0 input;
|
||||||
y := Resource.fld1 input
|
y := Resource.fld1 input
|
||||||
};
|
};
|
||||||
|
|
||||||
{-
|
|
||||||
main
|
|
||||||
(input : Resource)
|
|
||||||
(path : List (Pair Field Bool))
|
|
||||||
: Field :=
|
|
||||||
count path;
|
|
||||||
-}
|
|
||||||
|
11
tests/Casm/Compilation/positive/test078.juvix
Normal file
11
tests/Casm/Compilation/positive/test078.juvix
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
module test078;
|
||||||
|
|
||||||
|
import Stdlib.Prelude open;
|
||||||
|
|
||||||
|
fact' (acc : Nat) : Nat → Nat
|
||||||
|
| zero := acc
|
||||||
|
| (suc x) := assert (acc /= 0) >-> fact' (acc * suc x) x;
|
||||||
|
|
||||||
|
fact : Nat → Nat := fact' 1;
|
||||||
|
|
||||||
|
main : Nat := assert (fact 10 == 10 * fact 9) >-> fact 5 + fact 10 + fact 12;
|
1
tests/Casm/positive/out/test018.out
Normal file
1
tests/Casm/positive/out/test018.out
Normal file
@ -0,0 +1 @@
|
|||||||
|
0
|
13
tests/Casm/positive/test018.casm
Normal file
13
tests/Casm/positive/test018.casm
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
-- assertions
|
||||||
|
|
||||||
|
start:
|
||||||
|
[ap] = 10
|
||||||
|
[ap + 1] = 1
|
||||||
|
ap += 2
|
||||||
|
loop:
|
||||||
|
[ap] = [ap - 2] - 1
|
||||||
|
[ap + 1] = [ap - 1] * [ap - 2]
|
||||||
|
ap += 2
|
||||||
|
jmp loop if [ap - 2] != 0
|
||||||
|
[ap] = [ap - 1] - 3628800; ap++
|
||||||
|
assert [ap - 1]
|
Loading…
Reference in New Issue
Block a user