From: Mart Lubbers Date: Thu, 19 May 2016 14:22:25 +0000 (+0200) Subject: function dingen werken X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=6758e36a62b15fea8b7505f58b829ff4ff0ba94e;p=cc1516.git function dingen werken --- 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