function dingen werken
authorMart Lubbers <mart@martlubbers.net>
Thu, 19 May 2016 14:22:25 +0000 (16:22 +0200)
committerMart Lubbers <mart@martlubbers.net>
Thu, 19 May 2016 14:22:25 +0000 (16:22 +0200)
examples/codeGen.spl
gen.icl
parse.icl

index 53ed358..9982b4b 100644 (file)
@@ -1,8 +1,16 @@
+f(x) {
+       Int y = 2;
+       return 4;
+}
+
 main() {
-    Int x1 = 3;
-    Char x2 = '\n';
-    Bool x3 = True;
-    (Int, Char) x4 = (4, '\n');
-    [Bool] x5 = True : False : True : True : []; 
-    return x5;
+//    Int x1 = 3;
+//    Char x2 = '\n';
+//    Bool x3 = True;
+//    (Int, Char) x4 = (4, '\n');
+//    [Bool] x5 = True : False : True : True : []; 
+//     [Int] x1 = 42 : [];
+       Int x1 = 1;
+       Int x2 = f(x1);
+    return x1;
 }
diff --git a/gen.icl b/gen.icl
index 4bf1bb8..30bc819 100644 (file)
--- a/gen.icl
+++ b/gen.icl
@@ -44,7 +44,10 @@ gen (AST fds) = case evalRWST prog () ('Map'.newMap, labelStream) of
             Left (Error e) = Left e
             Right (_, p) = Right $ toString p
     where
-        prog = tell [Instr "bra" [L "main"] ""] >>| mapM_ g fds
+        prog = tell [
+                       Instr "bsr" [L "main"] "",
+                       Instr "halt" [] ""
+                       ] >>| mapM_ g fds
 
 //Current issues:
 //All VarDecls are added as function, how to deal with assignments?
@@ -96,7 +99,6 @@ instance g Op2 where
                    BiCons = abort "Shit, Cons, how to deal with this?"
 
 instance g Expr where
-//    g (VarExpr _ (VarDef k fs)) = load k >>= \instr-> tell [instr] //note: pure is pure for list, i.e. []
     g (IntExpr _ i) = tell [Instr "ldc" [Lit i] ""]
     g (CharExpr _ c) = tell [Instr "ldc" [Lit (toInt c)] ""]
        g (BoolExpr _ b) = tell [Instr "ldc" [Lit (if b TRUE FALSE)] ""]
@@ -113,14 +115,24 @@ instance g Expr where
                >>| g e2
                >>| tell [Instr "sth" [] ""]
                >>| tell [Instr "ajs" [Lit -1] ""]
-       g _ = abort "hoi"
-    g (FunExpr _ k es fs) = abort "FunExpr unsupported modderfokker"
- //       mapM g es >>| //put all arguments on the stack (todo: fix argument handling!)
- //       jump "bsr" k >>= \instr-> 
- //       tell [instr] >>| //actually branch to function
- //       tell [Instr "ldr" [Raw "RR"] ""] //push return value on stack, todo: check for VOID
-//
-//instance g Stmt where
+    g (VarExpr _ (VarDef k fs)) = getAdressbook >>= \ab->case 'Map'.get k ab of
+               Nothing = liftT (Left $ Error "PANIC: undefined variable")
+               Just (ADDR t) = tell [Instr "ldl" [Lit t] ""]
+               Just (LAB t) = liftT (Left $ Error "PANIC: variable and function name clash")
+               //load k >>= \instr-> tell [instr] //note: pure is pure for list, i.e. []
+    g (FunExpr _ k es fs) = 
+//             tell [Instr "ldr" [Raw "MP"] ("old frame pointer")]
+               mapM g es
+               >>| jump "bsr" k
+               >>| tell [Instr "ldr" [Raw "RR"] ""]
+
+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 $ "PANIC: jump should go to label")
+
+instance g Stmt where
 //    g (IfStmt cond th el) = 
 //        fresh >>= \elseLabel->
 //        fresh >>= \endLabel->
@@ -145,32 +157,27 @@ instance g Expr where
 //        abort "Shit, an assignment, figure out something with storing vars or something"
 //        //vars will be on stack in locals (possible pointers to heap)
 //    g (FunStmt _ _) = abort "CodeGen, FunStmt unused" //not used
-//    g (ReturnStmt Nothing)  = tell [Instr "ret" [] ""] //NOTE! Assumes only return address on stack, safe?
-//    g (ReturnStmt (Just e)) = 
-//        g e >>|
-//        tell [Instr "str" [Raw "RR"] ""] >>|
-//        g (ReturnStmt Nothing)
-
-instance g VarDecl where
-    g (VarDecl _ Nothing _ _) = liftT (Left $ Error "PANIC: untyped vardecl")
-    g (VarDecl _ (Just t) k e) = g e
-//             TupleType (t1, t2) = g e
-//             ListType t = abort "listtype"
-//             IdType _ = liftT (Left $ Error "PANIC: unresolved typevariable")
-//     t1 ->> t2 = abort "funtype" 
-//             VoidType = liftT (Left $ Error "PANIC: Void vardecl")
-//             _ = g e
+    g (ReturnStmt Nothing) = tell [Instr "unlink" [] ""]
+               >>| tell [Instr "ret" [] ""]
+    g (ReturnStmt (Just e)) = g e
+               >>| tell [Instr "str" [Raw "RR"] ""] 
+               >>| g (ReturnStmt Nothing)
+
+foldVarDecl :: Int VarDecl -> Gen Int
+foldVarDecl x (VarDecl _ _ k e) = g e 
+       >>| updateAdressbook (extend k (ADDR x)) >>| pure (x + 1)
 
 instance g FunDecl where
     g (FunDecl _ k _ _ vds stms) = 
         //varDecls can call the enclosing function, so first reserve a label for it 
         updateAdressbook (extend k (LAB k)) >>|
         tell [Lab k] >>|
+               tell [Instr "link" [Lit 0] ""] >>|
         //then generate functions for the VarDecls
         getAdressbook >>= \oldMap ->
-        mapM_ g vds  >>|
+        foldM foldVarDecl 1 vds  >>|
         //then the main function 
-//        mapM_ g stms >>|
+        mapM_ g stms >>|
         updateAdressbook (const oldMap) >>| pure ()
 //
 //load :: String -> Gen Instr
index 004c1f4..46a92e3 100644 (file)
--- a/parse.icl
+++ b/parse.icl
@@ -127,8 +127,6 @@ parseExpr = //Operators in order of binding strength
                parseBasicExpr :: Parser Token Expr
                parseBasicExpr = peekPos >>= \pos ->
                        (TupleExpr pos <$> (parseTuple parseExpr)) <|>
-                       (parseFunCall >>= \(ident, args)->parseFieldSelectors >>= \fs->
-                               pure $ FunExpr pos ident args fs) <|>
                        parseBBraces parseExpr <|>
                        trans1 EmptyListToken (EmptyListExpr pos) <|>
                        trans1 TrueToken (BoolExpr pos True) <|>
@@ -136,11 +134,14 @@ parseExpr = //Operators in order of binding strength
                        trans2 (NumberToken zero) (\(NumberToken i)->IntExpr pos i) <|>
                        trans2 (CharToken zero) (\(CharToken c)->CharExpr pos c) <|>
                        (Op1Expr pos <$> parseOp1 <*> parseExpr) <|>
+                       (parseFunCall >>= \(ident, args)->parseFieldSelectors >>= \fs->
+                               pure $ FunExpr pos ident args fs) <|>
                        (VarExpr pos <$> parseVarDef)
 
 parseFunCall :: Parser Token (String, [Expr])
-parseFunCall = tuple <$> parseIdent <*> (
-       (parseBBraces $ parseSepList CommaToken parseExpr) <|> pure [])
+parseFunCall = liftM2 tuple 
+       parseIdent 
+       (parseBBraces $ parseSepList CommaToken parseExpr)
 
 parseVarDef :: Parser Token VarDef
 parseVarDef = liftM2 VarDef parseIdent parseFieldSelectors