add arity to ADDR
authorMart Lubbers <mart@martlubbers.net>
Tue, 24 May 2016 13:14:47 +0000 (15:14 +0200)
committerMart Lubbers <mart@martlubbers.net>
Tue, 24 May 2016 13:14:47 +0000 (15:14 +0200)
gen.icl

diff --git a/gen.icl b/gen.icl
index 2828798..3a86ba3 100644 (file)
--- a/gen.icl
+++ b/gen.icl
@@ -33,7 +33,7 @@ FALSE :== 0
 :: SSMProgram :== [Instr]
 :: GenError = Error String
 :: Addressbook :== 'Map'.Map String Address
-:: Address = LAB String Int Int | ADDR Int
+:: Address = LAB String Int Int | ADDR Int Int
 :: Gen a :== RWST () SSMProgram (Addressbook, [Label]) (Either GenError) a
 
 labelStream :: [Label]
@@ -170,7 +170,7 @@ instance g Expr where
                >>| g e2
                >>| tell [Instr "stmh" [Lit 2] ""]
     g (VarExpr _ (VarDef k fs)) = getAdressbook >>= \ab->case 'Map'.get k ab of
-               Just (ADDR t) = tell [Instr "ldl" [Lit t] ""] >>| mapM_ g fs >>| pure ()
+               Just (ADDR t arity) = tell [Instr "ldl" [Lit t] ""] >>| mapM_ g fs >>| pure ()
                Just (LAB l _ fn) = tell 
                        [Instr "ldc" [Lit fn] ""
                        ,Instr "sth" [] ""
@@ -195,14 +195,16 @@ instance g Expr where
                                        [Instr "ajs" [Lit $ ~(length es)] "Clean arguments"
                                        ,Instr "ldr" [Raw "RR"] ""])
                //Identifier points to variable, thus higher order function
-               Just (ADDR t) = liftT (Left $ Error "FunExpr to addr")
+               Just (ADDR t arity) = if (arity <> (length es))
+                       ( liftT (Left $ Error "Variable is function and still not complete"))
+                       ( liftT (Left $ Error "Variable is function and can be executed"))
                Nothing = liftT (Left $ Error "Undefined function!!!")
 
 jump :: String String -> Gen ()
 jump instr k = getAdressbook >>= \ab->case 'Map'.get k ab of
        Nothing = liftT (Left $ Error $ concat ["PANIC: ", k, " not found as function"])
        Just (LAB t _ _) = tell [Instr instr [L t] (k +++"()")]
-       Just (ADDR t) = liftT (Left $ Error "Address as jump???")
+       Just (ADDR t arity) = liftT (Left $ Error "Address as jump???")
 
 instance g Stmt where
     g (IfStmt cond th el) = 
@@ -228,7 +230,7 @@ instance g Stmt where
         g e >>| getAdressbook >>= \ab->case 'Map'.get k ab of
             Nothing = liftT (Left $ Error $ concat ["PANIC: ", k, " not found as var"])
             Just (LAB t _ _) = liftT (Left $ Error $ "PANIC: cannot assign to function")
-            Just (ADDR t) = tell [Instr "stl" [Lit t] ""]
+            Just (ADDR t ar) = tell [Instr "stl" [Lit t] ""]
     g (FunStmt k es fs) = mapM_ g es 
         >>| jump "bsr" k
         >>| tell [Instr "ajs" [Lit (~(length es))] ""] //clean up args
@@ -243,18 +245,23 @@ instance g Stmt where
 foldVarDecl :: Int VarDecl -> Gen Int
 foldVarDecl x (VarDecl _ mt k e) = g e 
     >>| annote x k
-       >>| updateAdressbook (extend k (ADDR x))
+       >>| updateAdressbook (extend k (ADDR x $ arity $ fromJust mt))
        >>| pure (x + 1)
 
-addVars :: [String] -> (Addressbook -> Addressbook)
-addVars [] = id
-addVars [x:xs] = \ab->extend x (ADDR (-2 - (length xs))) (addVars xs ab)
+arity :: Type -> Int
+arity (_ ->> x) = 1 + arity x
+arity _ = 0
+
+addVars :: Type [String] -> (Addressbook -> Addressbook)
+addVars _ [] = id
+addVars (t ->> ts) [x:xs] = \ab->
+       extend x (ADDR (-2 - (length xs)) (arity t)) (addVars t xs ab)
 
 instance g FunDecl where
-    g (FunDecl _ k args _ vds stms) = 
+    g (FunDecl _ k args mt vds stms) = 
         //varDecls can call the enclosing function, so first reserve a label for it 
         getAdressbook >>= \oldMap ->
-               updateAdressbook (addVars args) >>|
+               updateAdressbook (addVars (fromJust mt) args) >>|
         tell [Lab k] >>|
                tell [Instr "link" [Lit 0] ""] >>|
         //add the vars