parse arithmetic nan
This commit is contained in:
@@ -11,6 +11,7 @@ import qualified Data.Char as Char
|
|||||||
import qualified Data.ByteString.Lazy.UTF8 as LBSUtf8
|
import qualified Data.ByteString.Lazy.UTF8 as LBSUtf8
|
||||||
import Control.Applicative ((<$>))
|
import Control.Applicative ((<$>))
|
||||||
import Control.Monad (when)
|
import Control.Monad (when)
|
||||||
|
import Numeric.IEEE (infinity, nan, nanWithPayload)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,11 +55,9 @@ tokens :-
|
|||||||
<0> "nan" { constToken $ TFloatLit nan }
|
<0> "nan" { constToken $ TFloatLit nan }
|
||||||
<0> "+nan" { constToken $ TFloatLit nan }
|
<0> "+nan" { constToken $ TFloatLit nan }
|
||||||
<0> "-nan" { constToken $ TFloatLit minusNaN }
|
<0> "-nan" { constToken $ TFloatLit minusNaN }
|
||||||
<0> @nanhex { constToken $ TFloatLit nan {- TODO: real hex rep parsing -}}
|
<0> $sign? @nanhex { parseNanSigned }
|
||||||
<0> "+" @nanhex { constToken $ TFloatLit nan {- TODO: real hex rep parsing -}}
|
|
||||||
<0> "-" @nanhex { constToken $ TFloatLit minusNaN {- TODO: real hex rep parsing -}}
|
|
||||||
<0> "inf" { constToken $ TFloatLit inf }
|
<0> "inf" { constToken $ TFloatLit inf }
|
||||||
<0> "+inf" { constToken $ TFloatLit inf }
|
<0> "+inf" { constToken $ TFloatLit inf }
|
||||||
<0> "-inf" { constToken $ TFloatLit minusInf }
|
<0> "-inf" { constToken $ TFloatLit minusInf }
|
||||||
<0> @keyword { tokenStr TKeyword }
|
<0> @keyword { tokenStr TKeyword }
|
||||||
<0> @linecomment ;
|
<0> @linecomment ;
|
||||||
@@ -99,11 +98,10 @@ isAllowedStringChar _userState (_pos, _rest, inp, _) _len _nextInp =
|
|||||||
let code = Char.ord char in
|
let code = Char.ord char in
|
||||||
code >= 0x20 && code /= 0x7f && char /= '"' && char /= '\\'
|
code >= 0x20 && code /= 0x7f && char /= '"' && char /= '\\'
|
||||||
|
|
||||||
minusNaN, nan, inf, minusInf :: Double
|
minusNaN, inf, minusInf :: Double
|
||||||
minusNaN = read "-NaN"
|
minusNaN = -nan
|
||||||
nan = read "NaN"
|
inf = infinity
|
||||||
inf = read "Infinity"
|
minusInf = -infinity
|
||||||
minusInf = read "-Infinity"
|
|
||||||
|
|
||||||
parseSign :: (Num a) => LBS.ByteString -> ((a -> a), Int64)
|
parseSign :: (Num a) => LBS.ByteString -> ((a -> a), Int64)
|
||||||
parseSign str =
|
parseSign str =
|
||||||
@@ -122,6 +120,12 @@ parseHexalSignedInt = token $ \(pos, _, s, _) len ->
|
|||||||
let num = readHexFromPrefix (len - 2 - slen) $ LBSUtf8.drop (2 + slen) s in
|
let num = readHexFromPrefix (len - 2 - slen) $ LBSUtf8.drop (2 + slen) s in
|
||||||
Lexeme pos $ TIntLit $ sign num
|
Lexeme pos $ TIntLit $ sign num
|
||||||
|
|
||||||
|
parseNanSigned :: AlexAction Lexeme
|
||||||
|
parseNanSigned = token $ \(pos, _, s, _) len ->
|
||||||
|
let (sign, slen) = parseSign s in
|
||||||
|
let num = readHexFromPrefix (len - 6 - slen) $ LBSUtf8.drop (6 + slen) s in
|
||||||
|
Lexeme pos $ TFloatLit $ sign $ fromIntegral num
|
||||||
|
|
||||||
parseDecimalSignedInt :: AlexAction Lexeme
|
parseDecimalSignedInt :: AlexAction Lexeme
|
||||||
parseDecimalSignedInt = token $ \(pos, _, s, _) len ->
|
parseDecimalSignedInt = token $ \(pos, _, s, _) len ->
|
||||||
let (sign, slen) = parseSign s in
|
let (sign, slen) = parseSign s in
|
||||||
|
|||||||
+20
-17
@@ -71,6 +71,7 @@ import Control.Monad (guard)
|
|||||||
import Numeric.Natural (Natural)
|
import Numeric.Natural (Natural)
|
||||||
import Data.Word (Word32, Word64)
|
import Data.Word (Word32, Word64)
|
||||||
import Data.Bits ((.|.))
|
import Data.Bits ((.|.))
|
||||||
|
import Numeric.IEEE (infinity, nan)
|
||||||
|
|
||||||
import Language.Wasm.Lexer (
|
import Language.Wasm.Lexer (
|
||||||
Token (
|
Token (
|
||||||
@@ -318,8 +319,7 @@ u32 { Lexeme _ (TIntLit (asUInt32 -> Just $$)) }
|
|||||||
i32 { Lexeme _ (TIntLit (asInt32 -> Just $$)) }
|
i32 { Lexeme _ (TIntLit (asInt32 -> Just $$)) }
|
||||||
i64 { Lexeme _ (TIntLit (asInt64 -> Just $$)) }
|
i64 { Lexeme _ (TIntLit (asInt64 -> Just $$)) }
|
||||||
unrestricted_int { Lexeme _ (TIntLit $$) }
|
unrestricted_int { Lexeme _ (TIntLit $$) }
|
||||||
f32 { Lexeme _ (TFloatLit (asFloat32 -> $$)) }
|
f64 { Lexeme _ (TFloatLit $$) }
|
||||||
f64 { Lexeme _ (TFloatLit (asFloat64 -> $$)) }
|
|
||||||
offset { Lexeme _ (TKeyword (asOffset -> Just $$)) }
|
offset { Lexeme _ (TKeyword (asOffset -> Just $$)) }
|
||||||
align { Lexeme _ (TKeyword (asAlign -> Just $$)) }
|
align { Lexeme _ (TKeyword (asAlign -> Just $$)) }
|
||||||
string { Lexeme _ (TStringLit (asString -> Just $$)) }
|
string { Lexeme _ (TStringLit (asString -> Just $$)) }
|
||||||
@@ -381,15 +381,14 @@ float32 :: { Float }
|
|||||||
| i32 { fromIntegral $1 }
|
| i32 { fromIntegral $1 }
|
||||||
| i64 { fromIntegral $1 }
|
| i64 { fromIntegral $1 }
|
||||||
| unrestricted_int { fromIntegral $1 }
|
| unrestricted_int { fromIntegral $1 }
|
||||||
| f32 { $1 }
|
| f64 { asFloat32 $1 }
|
||||||
|
|
||||||
float64 :: { Double }
|
float64 :: { Double }
|
||||||
: u32 { fromIntegral $1 }
|
: u32 { fromIntegral $1 }
|
||||||
| i32 { fromIntegral $1 }
|
| i32 { fromIntegral $1 }
|
||||||
| i64 { fromIntegral $1 }
|
| i64 { fromIntegral $1 }
|
||||||
| unrestricted_int { fromIntegral $1 }
|
| unrestricted_int { fromIntegral $1 }
|
||||||
| f32 { realToFrac $1 }
|
| f64 { $1 }
|
||||||
| f64 { realToFrac $1 }
|
|
||||||
|
|
||||||
plaininstr :: { PlainInstr }
|
plaininstr :: { PlainInstr }
|
||||||
-- control instructions
|
-- control instructions
|
||||||
@@ -801,9 +800,9 @@ function :: { [ModuleField] }
|
|||||||
: 'func' opt(ident) export_import_typeuse_locals_body { $3 $2 }
|
: 'func' opt(ident) export_import_typeuse_locals_body { $3 $2 }
|
||||||
|
|
||||||
export_import_typeuse_locals_body :: { Maybe Ident -> [ModuleField] }
|
export_import_typeuse_locals_body :: { Maybe Ident -> [ModuleField] }
|
||||||
: ')' { \i -> [MFFunc $ emptyFunction { ident = i }] }
|
: ')' { \i -> [MFFunc Nothing $ emptyFunction { ident = i }] }
|
||||||
| raw_instr list(instruction) ')' {
|
| raw_instr list(instruction) ')' {
|
||||||
\i -> [MFFunc $ emptyFunction { ident = i, body = $1 ++ concat $2 }]
|
\i -> [MFFunc Nothing $ emptyFunction { ident = i, body = $1 ++ concat $2 }]
|
||||||
}
|
}
|
||||||
| '(' export_import_typeuse_locals_body1 { $2 }
|
| '(' export_import_typeuse_locals_body1 { $2 }
|
||||||
|
|
||||||
@@ -817,7 +816,7 @@ import_typeuse_locals_body1 :: { Maybe Ident -> ModuleField }
|
|||||||
: 'import' name name ')' typeuse ')' {
|
: 'import' name name ')' typeuse ')' {
|
||||||
\ident -> MFImport $ Import $2 $3 $ ImportFunc ident $5
|
\ident -> MFImport $ Import $2 $3 $ ImportFunc ident $5
|
||||||
}
|
}
|
||||||
| typeuse_locals_body1 { MFFunc . $1 }
|
| typeuse_locals_body1 { MFFunc Nothing . $1 }
|
||||||
|
|
||||||
typeuse_locals_body1 :: { Maybe Ident -> Function }
|
typeuse_locals_body1 :: { Maybe Ident -> Function }
|
||||||
: 'type' typeidx ')' signature_locals_body {
|
: 'type' typeidx ')' signature_locals_body {
|
||||||
@@ -1100,10 +1099,7 @@ asInt64 val
|
|||||||
| otherwise = Nothing
|
| otherwise = Nothing
|
||||||
|
|
||||||
asFloat32 :: Double -> Float
|
asFloat32 :: Double -> Float
|
||||||
asFloat32 = realToFrac
|
asFloat32 v = realToFrac v
|
||||||
|
|
||||||
asFloat64 :: Double -> Double
|
|
||||||
asFloat64 = id
|
|
||||||
|
|
||||||
asOffset :: LBS.ByteString -> Maybe Natural
|
asOffset :: LBS.ByteString -> Maybe Natural
|
||||||
asOffset str = do
|
asOffset str = do
|
||||||
@@ -1337,7 +1333,7 @@ data DataSegment = DataSegment {
|
|||||||
data ModuleField =
|
data ModuleField =
|
||||||
MFType TypeDef
|
MFType TypeDef
|
||||||
| MFImport Import
|
| MFImport Import
|
||||||
| MFFunc Function
|
| MFFunc (Maybe Int) Function
|
||||||
| MFTable Table
|
| MFTable Table
|
||||||
| MFMem Memory
|
| MFMem Memory
|
||||||
| MFGlobal Global
|
| MFGlobal Global
|
||||||
@@ -1443,7 +1439,7 @@ desugarize fields =
|
|||||||
S.mems = map synMemoryToStruct $ mems mod,
|
S.mems = map synMemoryToStruct $ mems mod,
|
||||||
S.globals = map (synGlobalToStruct mod) $ globals mod,
|
S.globals = map (synGlobalToStruct mod) $ globals mod,
|
||||||
S.start = fmap (synStartToStruct mod) $ start mod,
|
S.start = fmap (synStartToStruct mod) $ start mod,
|
||||||
S.exports = synExportsToStruct mod fields
|
S.exports = synExportsToStruct mod $ appendIndexToFuncs fields
|
||||||
}
|
}
|
||||||
where
|
where
|
||||||
-- utils
|
-- utils
|
||||||
@@ -1468,7 +1464,7 @@ desugarize fields =
|
|||||||
extractTypeDef defs (MFType _) = defs -- should be extracted before implicit defs
|
extractTypeDef defs (MFType _) = defs -- should be extracted before implicit defs
|
||||||
extractTypeDef defs (MFImport Import { desc = ImportFunc _ typeUse }) =
|
extractTypeDef defs (MFImport Import { desc = ImportFunc _ typeUse }) =
|
||||||
matchTypeUse defs typeUse
|
matchTypeUse defs typeUse
|
||||||
extractTypeDef defs (MFFunc Function { funcType, body }) =
|
extractTypeDef defs (MFFunc _ Function { funcType, body }) =
|
||||||
extractTypeDefFromInstructions (matchTypeUse defs funcType) body
|
extractTypeDefFromInstructions (matchTypeUse defs funcType) body
|
||||||
extractTypeDef defs (MFGlobal Global { initializer }) =
|
extractTypeDef defs (MFGlobal Global { initializer }) =
|
||||||
extractTypeDefFromInstructions defs initializer
|
extractTypeDefFromInstructions defs initializer
|
||||||
@@ -1649,7 +1645,7 @@ desugarize fields =
|
|||||||
}
|
}
|
||||||
|
|
||||||
extractFunction :: [Function] -> ModuleField -> [Function]
|
extractFunction :: [Function] -> ModuleField -> [Function]
|
||||||
extractFunction funcs (MFFunc fun) = fun : funcs
|
extractFunction funcs (MFFunc _ fun) = fun : funcs
|
||||||
extractFunction funcs _ = funcs
|
extractFunction funcs _ = funcs
|
||||||
|
|
||||||
getLabelIdx :: FunCtx -> LabelIndex -> Maybe Natural
|
getLabelIdx :: FunCtx -> LabelIndex -> Maybe Natural
|
||||||
@@ -1806,6 +1802,13 @@ desugarize fields =
|
|||||||
extractStart' start _ = start
|
extractStart' start _ = start
|
||||||
|
|
||||||
-- exports
|
-- exports
|
||||||
|
appendIndexToFuncs :: [ModuleField] -> [ModuleField]
|
||||||
|
appendIndexToFuncs mf = reverse $ snd $ foldl' appendIndexToFunc (0, []) mf
|
||||||
|
where
|
||||||
|
appendIndexToFunc :: (Int, [ModuleField]) -> ModuleField -> (Int, [ModuleField])
|
||||||
|
appendIndexToFunc (idx, mf) (MFFunc _ fun) = (idx + 1, (MFFunc (Just idx) fun):mf)
|
||||||
|
appendIndexToFunc (idx, mf) f = (idx, f:mf)
|
||||||
|
|
||||||
synExportsToStruct :: Module -> [ModuleField] -> [S.Export]
|
synExportsToStruct :: Module -> [ModuleField] -> [S.Export]
|
||||||
synExportsToStruct mod (MFExport Export { name, desc = ExportFunc Nothing } : rest) =
|
synExportsToStruct mod (MFExport Export { name, desc = ExportFunc Nothing } : rest) =
|
||||||
let
|
let
|
||||||
@@ -1819,7 +1822,7 @@ desugarize fields =
|
|||||||
let
|
let
|
||||||
idx = fromIntegral $ case head rest' of
|
idx = fromIntegral $ case head rest' of
|
||||||
MFImport imp -> fromJust $ findIndex (== imp) funImports
|
MFImport imp -> fromJust $ findIndex (== imp) funImports
|
||||||
MFFunc fun -> length funImports + (fromJust $ findIndex (== fun) $ functions mod)
|
MFFunc (Just idx) fun -> length funImports + idx
|
||||||
_ -> error "export statement without index has to be followed with import or function"
|
_ -> error "export statement without index has to be followed with import or function"
|
||||||
in
|
in
|
||||||
map (\name -> S.Export name $ S.ExportFunc idx) names ++ synExportsToStruct mod rest'
|
map (\name -> S.Export name $ S.ExportFunc idx) names ++ synExportsToStruct mod rest'
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ compile file = do
|
|||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
files <- Directory.listDirectory "tests/samples"
|
files <- Directory.listDirectory "tests/samples"
|
||||||
-- let files = ["imports.wast"]
|
-- let files = ["float_memory.wast"]
|
||||||
scriptTestCases <- (`mapM` files) $ \file -> do
|
scriptTestCases <- (`mapM` files) $ \file -> do
|
||||||
content <- LBS.readFile $ "tests/samples/" ++ file
|
content <- LBS.readFile $ "tests/samples/" ++ file
|
||||||
let Right script = Parser.parseScript <$> Lexer.scanner content
|
let Right script = Parser.parseScript <$> Lexer.scanner content
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ library
|
|||||||
, utf8-string >=1.0
|
, utf8-string >=1.0
|
||||||
, cereal >= 0.5
|
, cereal >= 0.5
|
||||||
, vector >= 0.12
|
, vector >= 0.12
|
||||||
|
, ieee754 >= 0.8
|
||||||
build-tools:
|
build-tools:
|
||||||
alex >=3.1.3
|
alex >=3.1.3
|
||||||
, happy >=1.9.4
|
, happy >=1.9.4
|
||||||
|
|||||||
Reference in New Issue
Block a user