From 6758e36a62b15fea8b7505f58b829ff4ff0ba94e Mon Sep 17 00:00:00 2001
From: Mart Lubbers <mart@martlubbers.net>
Date: Thu, 19 May 2016 16:22:25 +0200
Subject: [PATCH] function dingen werken

---
 examples/codeGen.spl | 20 ++++++++++-----
 gen.icl              | 61 ++++++++++++++++++++++++--------------------
 parse.icl            |  9 ++++---
 3 files changed, 53 insertions(+), 37 deletions(-)

diff --git a/examples/codeGen.spl b/examples/codeGen.spl
index 53ed358..9982b4b 100644
--- a/examples/codeGen.spl
+++ b/examples/codeGen.spl
@@ -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
--- 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
diff --git a/parse.icl b/parse.icl
index 004c1f4..46a92e3 100644
--- 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
-- 
2.20.1