aboutsummaryrefslogtreecommitdiff
path: root/src/Micro/Asm/Sdcc.hs
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2022-09-14 20:15:49 +0100
committerJuan J. Martinez <jjm@usebox.net>2022-09-14 20:15:49 +0100
commit139f9d9e354eaeb6e9f1ebf6bc5abe2e903a55e2 (patch)
treeeb7aed280c68948a25d3522103d87dafc34597e0 /src/Micro/Asm/Sdcc.hs
parent30f4498d2c62b77d823ffe1292387e66ed047c25 (diff)
downloadmicro-lang-hs-139f9d9e354eaeb6e9f1ebf6bc5abe2e903a55e2.tar.gz
micro-lang-hs-139f9d9e354eaeb6e9f1ebf6bc5abe2e903a55e2.zip
Playing with some ideas
Diffstat (limited to 'src/Micro/Asm/Sdcc.hs')
-rw-r--r--src/Micro/Asm/Sdcc.hs44
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