diff options
author | Juan J. Martinez <jjm@usebox.net> | 2022-09-14 20:15:49 +0100 |
---|---|---|
committer | Juan J. Martinez <jjm@usebox.net> | 2022-09-14 20:15:49 +0100 |
commit | 139f9d9e354eaeb6e9f1ebf6bc5abe2e903a55e2 (patch) | |
tree | eb7aed280c68948a25d3522103d87dafc34597e0 | |
parent | 30f4498d2c62b77d823ffe1292387e66ed047c25 (diff) | |
download | micro-lang-hs-139f9d9e354eaeb6e9f1ebf6bc5abe2e903a55e2.tar.gz micro-lang-hs-139f9d9e354eaeb6e9f1ebf6bc5abe2e903a55e2.zip |
Playing with some ideas
-rw-r--r-- | src/Micro/Asm/Sdcc.hs | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/src/Micro/Asm/Sdcc.hs b/src/Micro/Asm/Sdcc.hs index a645129..b582819 100644 --- a/src/Micro/Asm/Sdcc.hs +++ b/src/Micro/Asm/Sdcc.hs @@ -38,9 +38,6 @@ area name = "\n\t.area " ++ name globl :: String -> String globl id = "\t.globl " ++ id -code :: [String] -code = [area "_CODE"] - data Output = Output { oPre :: [String], oInit :: [String], @@ -52,23 +49,34 @@ emit :: A.Expr -> Output emit x = case x of (A.Module name _) -> o {oPre = [module' name, optsdcc, ""]} - (A.Func ident params ret body priv anon pos) -> do - let out = map emit body - let code = concat (map oCode out) - o - { oPre = if priv then [] else [globl $ toIdent ident], - oCode = [toLabel ident priv] ++ code ++ (if last code /= "\tret" then ["\tret"] else []) - } (A.Var id typ val priv False _) -> o { oPre = if priv then [] else [globl $ toIdent id], oData = [toLabel id priv, "\t" ++ toData typ], - oInit = ["__xinit" ++ toLabel id True, "\t" ++ toInit typ val] + oInit = ["__init" ++ toLabel id True, "\t" ++ toInit typ val] } - (A.Call (A.Variable id _) _ _) -> o {oCode = ["\tcall " ++ toIdent id]} - (A.Return (Just value) _) -> o {oCode = ["\tld hl, ???", "\tret"]} - (A.Return Nothing _) -> o {oCode = ["\tret"]} - _ -> o + (A.Num v _) -> o {oCode = ["\tld a, #" ++ show v]} + (A.Variable id _) -> o {oCode = ["\tld a, (" ++ toIdent id ++ ")"]} + -- cases where constant folding didn't happen + (A.BinOp A.Plus _ (A.Num a _) (A.Num b _)) -> o {oCode = [show a ++ "+" ++ show b]} + (A.BinOp A.Minus _ (A.Num a _) (A.Num b _)) -> o {oCode = [show a ++ "-" ++ show b]} + (A.BinOp A.Mul _ (A.Num a _) (A.Num b _)) -> o {oCode = [show a ++ "*" ++ show b]} + (A.BinOp A.Div _ (A.Num a _) (A.Num b _)) -> o {oCode = [show a ++ "/" ++ show b]} + (A.BinOp A.Plus _ a (A.Num 1 _)) -> + o {oCode = oCode (emit a) ++ ["\tinc a"]} + (A.BinOp A.Plus _ a@(A.Variable _ _) (A.Num v _)) -> + o {oCode = oCode (emit a) ++ ["\tadd #" ++ show v]} + (A.BinOp A.Plus _ a b) -> + o {oCode = oCode (emit a) ++ ["\tld c, a"] ++ oCode (emit b) ++ ["\tadd c"]} + (A.BinOp A.Minus _ a (A.Num 1 _)) -> + o {oCode = oCode (emit a) ++ ["\tdec a"]} + (A.BinOp A.Minus _ a@(A.Variable _ _) (A.Num v _)) -> + o {oCode = oCode (emit a) ++ ["\tsub #" ++ show v]} + (A.BinOp A.Minus _ a b) -> + o {oCode = oCode (emit a) ++ ["\tld c, a"] ++ oCode (emit b) ++ ["\tsub c"]} + (A.BinOp A.Assign _ (A.Variable id _) b) -> + o {oCode = oCode (emit b) ++ ["\tld (" ++ toIdent id ++ "), a"]} + _ -> o {oCode = [";; unimplemented " ++ show x]} where o = Output [] [] [] [] @@ -76,7 +84,7 @@ generate :: String -> [A.Expr] -> String generate version ast = do out <- pure $ map emit ast pre <- pure $ concat $ map oPre out - dat <- pure $ ["\n\t.area _DATA", "\t.area _INITIALIZED"] ++ concat (map oData out) - code <- pure $ ["\n\t.area _CODE"] ++ concat (map oCode out) - init <- pure $ ["\n\t.area _INITIALIZER"] ++ concat (map oInit out) ++ ["\n\t.area _GSINIT", "\t.area _GSFINAL"] + dat <- pure $ [area "_DATA", area "_INITIALIZED"] ++ concat (map oData out) + code <- pure $ [area "_CODE"] ++ concat (map oCode out) ++ ["hlt0:", "\tjr hlt0"] + init <- pure $ [area "_INITIALIZER"] ++ concat (map oInit out) ++ [area "_GSINIT", area "_GSFINAL"] unlines $ header version ++ pre ++ dat ++ code ++ init |