diff options
author | Marvin Borner | 2022-03-06 00:39:46 +0100 |
---|---|---|
committer | Marvin Borner | 2022-03-06 00:39:46 +0100 |
commit | a570892ef603aebba28ce9617fcd928df2d7761c (patch) | |
tree | 05d0f7331ad8f6accc5f72efc92587792550212e | |
parent | 13b00d16f1bec54002897b27fa1b78f4da281160 (diff) |
Assembly required
-rw-r--r-- | lib.fun | 2 | ||||
-rw-r--r-- | src/Fun/Generator.hs | 48 | ||||
-rw-r--r-- | src/Fun/Tree.hs | 1 |
3 files changed, 47 insertions, 4 deletions
@@ -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) = |