diff options
Diffstat (limited to 'src/Fun/Generator.hs')
-rw-r--r-- | src/Fun/Generator.hs | 48 |
1 files changed, 45 insertions, 3 deletions
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 |