@@ -161,7 +161,7 @@ data Data
161161 | DList [Data ]
162162 | DNone
163163 | DChar Char
164- | DFuncRef String [Data ]
164+ | DFuncRef String [Data ] [( String , Data )]
165165 | DMap (Data. Map String Data )
166166 | DTypeQuery String
167167 | DCPtr WordPtr
@@ -185,7 +185,7 @@ instance Show Data where
185185 show (DList x) = show x
186186 show DNone = " None"
187187 show (DChar x) = show x
188- show (DFuncRef x args) = " <" ++ x ++ " (" ++ show args ++ " )>"
188+ show (DFuncRef x args _ ) = " <" ++ x ++ " (" ++ show args ++ " )>"
189189 show (DMap x) = show x
190190 show (DTypeQuery x) = " TypeQuery " ++ x
191191 show (DCPtr x) = " CPtr " ++ show x
@@ -320,6 +320,31 @@ run' program = do
320320 modify $ \ vm -> vm{pc = vm. pc + 1 }
321321 gets running >>= flip when (run' program)
322322
323+ instance Real Data where
324+ toRational (DInt x) = toRational x
325+ toRational (DFloat x) = toRational x
326+ toRational (DDouble x) = toRational x
327+ toRational x = error $ " Cannot convert " ++ show x ++ " to Rational"
328+
329+ instance Enum Data where
330+ toEnum = DInt
331+ fromEnum (DInt x) = x
332+ fromEnum (DFloat x) = round x
333+ fromEnum (DDouble x) = round x
334+ fromEnum x = error $ " Cannot convert " ++ show x ++ " to Int"
335+
336+ instance Integral Data where
337+ quot (DInt x) (DInt y) = DInt $ quot x y
338+ quot _ _ = undefined
339+ rem (DInt x) (DInt y) = DInt $ rem x y
340+ rem _ _ = undefined
341+ quotRem (DInt x) (DInt y) = (DInt $ quot x y, DInt $ rem x y)
342+ quotRem _ _ = undefined
343+ toInteger (DInt x) = toInteger x
344+ toInteger (DFloat x) = round x
345+ toInteger (DDouble x) = round x
346+ toInteger x = error $ " Cannot convert " ++ show x ++ " to Integer"
347+
323348instance Num Data where
324349 (+) (DInt x) (DInt y) = DInt $ x + y
325350 (+) (DFloat x) (DFloat y) = DFloat $ x + y
@@ -435,6 +460,7 @@ instance Storable Data where
435460 alignment _ = 4
436461 peek _ = error " peek"
437462 poke ptr (DInt x) = poke (castPtr ptr) x
463+ poke ptr (DFloat x) = poke (castPtr ptr) x
438464 poke ptr (DString x) = poke (castPtr ptr) (unsafePerformIO $ newCString x)
439465 poke ptr (DMap x) = do
440466 let values = Data.Map. elems (clearMap x)
@@ -561,7 +587,8 @@ runInstruction (Push d) = stackPush d
561587-- runInstruction (PushPf name nArgs) = stackPopN nArgs >>= \args -> stackPush $ DFuncRef name args
562588runInstruction (PushPf name nArgs) = do
563589 (label, _) <- findLabelFuzzy name
564- stackPopN nArgs >>= \ args -> stackPush $ DFuncRef label args
590+ locals <- gets (locals . safeHead . callStack)
591+ stackPopN nArgs >>= \ args -> stackPush $ DFuncRef label args locals
565592runInstruction Pop = void stackPop
566593runInstruction StackLength = stackLen >>= stackPush . DInt . fromIntegral
567594-- Arithmetic
@@ -575,8 +602,7 @@ runInstruction Abs =
575602 DInt num -> DInt $ abs num
576603 DFloat num -> DFloat $ abs num
577604 _ -> error $ " Cannot take absolute value of " ++ show x
578- -- runInstruction Mod = stackPopN 2 >>= \[y, x] -> stackPush $ x `mod` y
579- runInstruction Mod = error " Mod not implemented"
605+ runInstruction Mod = stackPopN 2 >>= \ [y, x] -> stackPush $ x `mod` y
580606-- IO
581607runInstruction (Builtin Print ) = do
582608 vm <- get
@@ -610,9 +636,10 @@ runInstruction (Call x) = modify $ \vm -> vm{pc = fromMaybe (error $ "Label not
610636runInstruction (CallLocal x) = modify $ \ vm -> vm{pc = fromMaybe (error $ " Label not found: " ++ x) $ lookup x $ labels vm, callStack = StackFrame {returnAddress = pc vm, locals = (head (callStack vm)). locals} : callStack vm}
611637runInstruction CallS =
612638 stackPop >>= \ d -> case d of
613- DFuncRef x args -> do
639+ DFuncRef x args locals -> do
614640 stackPushN args
615641 runInstruction $ Call x
642+ forM_ locals $ \ (name, value) -> runInstruction (Push value) >> runInstruction (LStore name)
616643 _ -> error $ " Cannot call " ++ show d
617644runInstruction (Jmp x) = do
618645 (_, n) <- findLabelFuzzy x
@@ -696,6 +723,7 @@ runInstruction Length =
696723 _ -> stackPop >>= \ case DList l -> stackPush $ DInt $ length l; DString s -> stackPush $ DInt $ length s; _ -> error " Invalid type for length"
697724-- Type
698725runInstruction Cast = do
726+ -- stackPopN 2 >>= \(x : y : _) -> stackPushN [y, x]
699727 to <- stackPop
700728 stackPop >>= \ case
701729 (DInt x) -> stackPush $ case to of
@@ -755,7 +783,7 @@ runInstruction TypeOf =
755783 DList _ -> stackPush $ DString " List"
756784 DNone -> stackPush $ DString " None"
757785 DChar _ -> stackPush $ DString " Char"
758- DFuncRef _ _ -> stackPush $ DString " FuncRef"
786+ DFuncRef {} -> stackPush $ DString " FuncRef"
759787 DMap m -> do
760788 case Data.Map. lookup " __name" m of
761789 Just (DString name) -> stackPush $ DString name
@@ -776,7 +804,7 @@ runInstruction TypeEq =
776804 (DList _, DList _) -> True
777805 (DNone , DNone ) -> True
778806 (DChar _, DChar _) -> True
779- (DFuncRef _ _ , DFuncRef _ _ ) -> True
807+ (DFuncRef {} , DFuncRef {} ) -> True
780808 (DMap a, DMap b) -> do
781809 not (isJust (Data.Map. lookup " __name" a) && isJust (Data.Map. lookup " __name" b)) || (Data.Map. lookup " __name" a == Data.Map. lookup " __name" b)
782810 (DMap m, DTypeQuery tq) -> do
@@ -792,7 +820,7 @@ runInstruction TypeEq =
792820 (DList _, DTypeQuery s) -> s == " List"
793821 (DNone , DTypeQuery s) -> s == " None"
794822 (DChar _, DTypeQuery s) -> s == " Char"
795- (DFuncRef _ _ , DTypeQuery s) -> s == " FuncRef"
823+ (DFuncRef {} , DTypeQuery s) -> s == " FuncRef"
796824 _ -> False
797825runInstruction (PackList n) = stackPopN n >>= stackPush . DList
798826runInstruction (Mov n dat) = do
0 commit comments