Skip to content
This repository has been archived by the owner on Dec 5, 2019. It is now read-only.

Commit

Permalink
Implemented code generation for table constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
Laura Savino committed Jun 19, 2012
1 parent f1014c8 commit c60f62e
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 16 deletions.
88 changes: 73 additions & 15 deletions generator.hs
Expand Up @@ -12,6 +12,11 @@ data GeneratorState = GeneratorState {
tmpHandle :: Handle
}

data TableConstructorState = TableConstructorState {
generatorState :: GeneratorState,
nextIndex :: Int
}

putStatement :: GeneratorState -> String -> IO GeneratorState
putStatement s line = do
hPutStrLn (tmpHandle s) ("\t" ++ line)
Expand All @@ -29,21 +34,9 @@ putArguments s (expr : args) = do
finalState <- putArguments nextState args
return finalState

putExpression :: GeneratorState -> Expression -> IO GeneratorState

putExpression s NilLiteral = do
putStatement s ("call %lua_pushnil_fp @lua_pushnil (%lua_State* %state)")

putExpression s (BooleanLiteral True) = do
putStatement s ("call %lua_pushboolean_fp @lua_pushboolean (%lua_State* %state, i32 1)")

putExpression s (BooleanLiteral False) = do
putStatement s ("call %lua_pushboolean_fp @lua_pushboolean (%lua_State* %state, i32 0)")

putExpression s (NumberLiteral num) = do
putStatement s ("call %lua_pushnumber_fp @lua_pushnumber (%lua_State* %state, %lua_Number " ++ (show num) ++ ")")

putExpression s (StringLiteral str) = do
-- Emits code to push a string (with explicit length) onto the stack
putString :: GeneratorState -> String -> IO GeneratorState
putString s str = do
let outFD = outputHandle s
c = counter s
finalState = GeneratorState {
Expand All @@ -61,6 +54,22 @@ putExpression s (StringLiteral str) = do
putStatement finalState ("call %lua_pushlstring_fp @lua_pushlstring (%lua_State* %state, i8* %string" ++ (show c) ++ ", i64 " ++ (show strLen) ++ ")")
return finalState

putExpression :: GeneratorState -> Expression -> IO GeneratorState

putExpression s NilLiteral = do
putStatement s ("call %lua_pushnil_fp @lua_pushnil (%lua_State* %state)")

putExpression s (BooleanLiteral True) = do
putStatement s ("call %lua_pushboolean_fp @lua_pushboolean (%lua_State* %state, i32 1)")

putExpression s (BooleanLiteral False) = do
putStatement s ("call %lua_pushboolean_fp @lua_pushboolean (%lua_State* %state, i32 0)")

putExpression s (NumberLiteral num) = do
putStatement s ("call %lua_pushnumber_fp @lua_pushnumber (%lua_State* %state, %lua_Number " ++ (show num) ++ ")")

putExpression s (StringLiteral str) = putString s str

putExpression s (NotExpression expr) = do
s2 <- putExpression s expr

Expand Down Expand Up @@ -99,6 +108,55 @@ putExpression s (FunctionCall name args) = do
putStatement finalState ("call %lua_call_fp @lua_call (%lua_State* %state, i32 " ++ (show $ length args) ++ ", i32 1)")
return finalState

putExpression s (TableConstructor fields) = do
putStatement s ("call %lua_createtable_fp @lua_createtable (%lua_State* %state, i32 0, i32 0)")

let tableState = TableConstructorState { generatorState = s, nextIndex = 1 }
finalTableState <- putFields tableState fields

return $ generatorState finalTableState

putFields :: TableConstructorState -> [TableField] -> IO TableConstructorState
putFields s [] = return s
putFields s ((TableField key value) : remaining) = do
s2 <- putFieldKey s key
gs3 <- putExpression (generatorState s2) value

let nextState = TableConstructorState {
generatorState = gs3,
nextIndex = (nextIndex s2)
}

finalState <- putFields nextState remaining
return finalState

putFieldKey :: TableConstructorState -> TableKey -> IO TableConstructorState

putFieldKey s (TableExpressionKey expr) = do
nextGeneratorState <- putExpression (generatorState s) expr
return $ TableConstructorState {
generatorState = nextGeneratorState,
nextIndex = (nextIndex s)
}

putFieldKey s (TableNameKey name) = do
nextGeneratorState <- putString (generatorState s) (show name)
return $ TableConstructorState {
generatorState = nextGeneratorState,
nextIndex = (nextIndex s)
}

putFieldKey s TableImplicitKey = do
let index = (nextIndex s)
gs = (generatorState s)

nextGeneratorState <- putStatement gs ("call %lua_pushnumber_fp @lua_pushnumber (%lua_State* %state, %lua_Number " ++ (show index) ++ ")")

return $ TableConstructorState {
generatorState = nextGeneratorState,
nextIndex = index + 1
}

-- Writes the file's header, the root of the AST, and the footer
putTopLevelExpression :: Handle -> Expression -> IO ()
putTopLevelExpression fd exp = do
Expand Down
2 changes: 1 addition & 1 deletion input.lua
@@ -1 +1 @@
print("foo", not false, nil)
print({ "foo", not false, nil })

0 comments on commit c60f62e

Please sign in to comment.