-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
231cf2a
commit ff76ce8
Showing
9 changed files
with
371 additions
and
237 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
module Ast.Parser.Asm where | ||
|
||
import qualified Ast.Parser.Utils as PU | ||
import qualified Ast.Types as AT | ||
import qualified Data.Maybe as DM | ||
import qualified Text.Megaparsec as M | ||
import qualified Text.Megaparsec.Char as MC | ||
|
||
parseAsm :: PU.Parser AT.Expr -> PU.Parser AT.AsmExpr | ||
parseAsm ap = M.between (PU.symbol "{") (PU.symbol "}") $ do | ||
code <- PU.symbol "code ->" *> PU.lexeme anyString | ||
constraints <- PU.symbol "constraints ->" *> PU.lexeme parseAsmConstraint | ||
args <- PU.symbol "args ->" *> M.between (PU.symbol "(") (PU.symbol ")") (M.many ap) | ||
sideEffects <- PU.symbol "side_effects ->" *> PU.lexeme PU.parseBool | ||
alignStack <- PU.symbol "align_stack ->" *> PU.lexeme PU.parseBool | ||
return $ AT.AsmExpr code constraints args sideEffects alignStack | ||
|
||
parseAsmConstraint :: PU.Parser AT.AsmConstraint | ||
parseAsmConstraint = M.between (MC.char '"') (MC.char '"') $ do | ||
output <- M.optional parseConstraintOutput | ||
inputs <- M.optional $ sep *> M.sepBy parseConstraintInput sep | ||
return $ AT.AsmConstraint (DM.fromMaybe "" output) $ DM.fromMaybe [] inputs | ||
where | ||
sep = MC.string "," | ||
|
||
parseConstraintInput :: PU.Parser String | ||
parseConstraintInput = M.choice [MC.string "r", MC.string "m"] | ||
|
||
parseConstraintOutput :: PU.Parser String | ||
parseConstraintOutput = MC.char '=' *> M.choice [MC.string "r", MC.string "m"] | ||
|
||
anyString :: PU.Parser String | ||
anyString = M.between (MC.char '\"') (MC.char '\"') $ M.many PU.parseStringChar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
module Ast.Parser.AsmSpec (spec) where | ||
|
||
import qualified Ast.Parser.Asm as PA | ||
import qualified Ast.Parser.Expr as PE | ||
import qualified Ast.Parser.State as PS | ||
import qualified Ast.Parser.Utils as PU | ||
import qualified Ast.Types as AT | ||
import qualified Control.Monad.State as S | ||
import Test.Hspec | ||
import qualified Text.Megaparsec as M | ||
|
||
spec :: Spec | ||
spec = do | ||
let parse input = do | ||
(result, _) <- S.runStateT (M.runParserT (PA.parseAsm PE.parseExpr) "" input) PS.parserState | ||
return result | ||
let normalizeAsm asm = asm {AT.asmArgs = map PU.normalizeExpr $ AT.asmArgs asm} | ||
|
||
describe "parseAsm" $ do | ||
it "parses a simple assembly expression" $ do | ||
let input = "{ code -> \"nop\" constraints -> \"\" args -> () side_effects -> false align_stack -> false }" | ||
result <- parse input | ||
let expected = Right $ AT.AsmExpr "nop" (AT.AsmConstraint "" []) [] False False | ||
result `shouldBe` expected | ||
|
||
it "parses a move expression" $ do | ||
let input = "{ code -> \"mov $0, 42\" constraints -> \"=r\" args -> () side_effects -> false align_stack -> false }" | ||
result <- parse input | ||
let expected = Right $ AT.AsmExpr "mov $0, 42" (AT.AsmConstraint "r" []) [] False False | ||
result `shouldBe` expected | ||
|
||
it "parses an add expression" $ do | ||
let input = "{ code -> \"add $0, $1\" constraints -> \"=r,r\" args -> (a b) side_effects -> false align_stack -> false }" | ||
result <- parse input | ||
let normalizedResult = normalizeAsm <$> result | ||
let expected = Right $ AT.AsmExpr "add $0, $1" (AT.AsmConstraint "r" ["r"]) [AT.Var PU.normalizeLoc "a" AT.TUnknown, AT.Var PU.normalizeLoc "b" AT.TUnknown] False False | ||
normalizedResult `shouldBe` expected | ||
|
||
it "parses an complex expression" $ do | ||
let input = "{ code -> \"mov $0, 0x1b; call printf\" constraints -> \"\" args -> (\"\x1b[H\") side_effects -> true align_stack -> false }" | ||
result <- parse input | ||
let normalizedResult = normalizeAsm <$> result | ||
let expected = Right $ AT.AsmExpr "mov $0, 0x1b; call printf" (AT.AsmConstraint "" []) [AT.Lit PU.normalizeLoc $ AT.LArray [AT.LChar '\x1b', AT.LChar '[', AT.LChar 'H']] True False | ||
normalizedResult `shouldBe` expected |
Oops, something went wrong.