aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2022-03-06 00:39:46 +0100
committerMarvin Borner2022-03-06 00:39:46 +0100
commita570892ef603aebba28ce9617fcd928df2d7761c (patch)
tree05d0f7331ad8f6accc5f72efc92587792550212e
parent13b00d16f1bec54002897b27fa1b78f4da281160 (diff)
Assembly required
-rw-r--r--lib.fun2
-rw-r--r--src/Fun/Generator.hs48
-rw-r--r--src/Fun/Tree.hs1
3 files changed, 47 insertions, 4 deletions
diff --git a/lib.fun b/lib.fun
index 643149b..8d5f79d 100644
--- a/lib.fun
+++ b/lib.fun
@@ -1,2 +1,2 @@
_start :+: _void % danger-void danger-asm
-: _asm "xor ebx, ebx\nxor eax, eax\nmov al, 0x1\nint 0x80"
+: _asm "xor ebx, ebx" "xor eax, eax" "mov al, 0x1" "int 0x80"
diff --git a/src/Fun/Generator.hs b/src/Fun/Generator.hs
index a3c2728..ae80d66 100644
--- a/src/Fun/Generator.hs
+++ b/src/Fun/Generator.hs
@@ -7,7 +7,49 @@ import Fun.Typer
data GenerateError = GenerateError String
+-- TODO: There's something about a lifted ++ as alternative here I think
+concatEither :: Either GenerateError [String] -> Either GenerateError String
+concatEither (Left err ) = Left err
+concatEither (Right strs) = Right $ concat strs
+
+generatePattern :: Tree -> FunctionPattern -> Either GenerateError String
+generatePattern t (FunctionPattern []) = Right ""
+generatePattern t _ = Left $ GenerateError "not implemented"
+
+generateInternalAsmArgs :: [FunctionArgument] -> [Either GenerateError String]
+generateInternalAsmArgs [FunctionString x] = [Right x]
+generateInternalAsmArgs ((FunctionString x) : xs) =
+ [Right x] ++ [Right "\n"] ++ (generateInternalAsmArgs xs)
+generateInternalAsmArgs _ = [Left $ GenerateError "invalid _asm arguments"]
+
+generateFunctionCall :: Tree -> FunctionBody -> Either GenerateError String
+generateFunctionCall t (FunctionBodyCall "_asm" args) =
+ concatEither $ sequence $ generateInternalAsmArgs args
+generateFunctionCall t (FunctionBodyCall name args) =
+ Left $ GenerateError "not implemented"
+
+generateBody :: Tree -> FunctionBody -> Either GenerateError String
+generateBody t c@(FunctionBodyCall _ _) = generateFunctionCall t c
+generateBody t (FunctionBodyInfixCall name args) =
+ Left $ GenerateError "infix function call not implemented"
+generateBody t (FunctionBodyValue value) =
+ Left $ GenerateError "value not implemented"
+generateBody t (FunctionBodySub sub) = generateBody t sub
+
+generateDefinition :: Tree -> FunctionDefinition -> Either GenerateError String
+generateDefinition t (FunctionDefinition pattern body) =
+ concatEither $ sequence $ [generatePattern t pattern, generateBody t body]
+
+generateFunction :: Tree -> Block -> Either GenerateError String
+generateFunction t (FunctionBlock decl defns) =
+ let defn = concatEither $ sequence $ map (\d -> generateDefinition t d) defns
+ in case defn of
+ Left _ -> defn
+ Right d -> Right $ (dName decl) ++ ":\n" ++ d
+
+-- TODO: Generate all used functions directly instead
generateAsm :: Tree -> Either GenerateError String
-generateAsm (Tree t) = Right $ show t
--- generateAsm t =
--- Left $ GenerateError $ show $ getFunction t "_start" [InternalType "_void"]
+-- generateAsm (Tree t) = Right $ show t
+generateAsm t = case getFunction t "_start" [InternalType "_void"] of
+ Nothing -> Left $ GenerateError "invalid/missing _start function"
+ Just f -> generateFunction t f
diff --git a/src/Fun/Tree.hs b/src/Fun/Tree.hs
index 7b87853..943ecc3 100644
--- a/src/Fun/Tree.hs
+++ b/src/Fun/Tree.hs
@@ -59,6 +59,7 @@ data FunctionArgument = FunctionName String | FunctionInfixName String | Functio
----
-- TODO: This can be optimized
+-- TODO: Respect visibility
getFunction :: Tree -> String -> FunctionSignature -> Maybe Block
getFunction (Tree ps) f sig =
let fromProgram (Program bs) =