Skip to content

Commit 485af4b

Browse files
committed
Added type information pragmas
1 parent 3b4119f commit 485af4b

File tree

4 files changed

+145
-18
lines changed

4 files changed

+145
-18
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
*.o
33
*.gch
44

5+
# Misc
6+
tags
7+
58
# Temporary files made by SimGrid
69
smpitmp-*
710

src/fpopt/app/Main.hs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
module Main where
22

3-
import Parser
4-
import System.Environment
3+
import Parser
4+
import System.Environment
5+
import qualified Data.Text.IO as T
56

67
usage = "usage: stack exec fpopt <filename>"
78

@@ -17,6 +18,7 @@ main = do
1718
parseMain :: String -> IO ()
1819
parseMain filename = do
1920
putStrLn ("# Generated from " ++ filename)
20-
-- s <- readFile filename
21-
-- parseTest parser s -- run_parser is more robust with errors
21+
s <- readFile filename
22+
let m = run_parser parser filename s
23+
putStrLn $ "# " ++ (show m)
2224

src/fpopt/src/Lexer.hs

+10-8
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@ import qualified Text.Parsec.Token as T
77

88
-- The lexer is not a separate phase, but provides useful building blocks
99
-- There are many other token types in this module, we use only a subset
10-
tmatlab = emptyDef {
11-
T.commentLine = "#",
12-
T.identStart = letter,
13-
T.identLetter = alphaNum,
14-
T.reservedNames = ["zeros", "ones", "eye"],
15-
T.reservedOpNames = ["+", "*", "\\", "-", "="]
16-
}
10+
tmatlab = emptyDef
11+
{ T.commentLine = "%"
12+
, T.nestedComments = False
13+
, T.identStart = letter
14+
, T.identLetter = alphaNum
15+
, T.reservedNames = ["zeros", "ones", "eye", "rand", "double", "float"]
16+
, T.reservedOpNames = ["+", "*", "/", "-", "=", "::"]
17+
, T.caseSensitive = True
18+
}
1719
lexer = T.makeTokenParser tmatlab
1820

1921
-- The useful building blocks
2022
identifier = T.identifier lexer
21-
whiteSpace = T.whiteSpace lexer
23+
whiteSpace = T.whiteSpace lexer -- Comments are whitespace
2224
parens = T.parens lexer
2325
integer = T.integer lexer
2426
reservedOp = T.reservedOp lexer

src/fpopt/src/Parser.hs

+126-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,136 @@
1+
{-# LANGUAGE FlexibleContexts #-}
2+
13
module Parser
24
( run_parser
5+
, parser
36
) where
47

5-
import Lexer -- We only use a few features of the Lexer
8+
import Lexer
9+
10+
import Data.Functor.Identity
611
import Text.Parsec
712
import Text.Parsec.String
813
import Text.Parsec.Expr hiding (Operator)
914

10-
run_parser :: Parser a -> String -> a
11-
run_parser p str = case parse p "source name" str of
15+
-- A TMatlab (Typed Matlab) program consists of
16+
-- a list of statements separated by semicolons or newlines
17+
-- If the semicolon is missing from the statement, the result of
18+
-- the expression is printed in the "OUTPUT" section of the Satire DSL
19+
-- Statements consist only of the form V = E; where V is a variable
20+
-- and E is an expression or initialization statement
21+
type TMatlab = [Command]
22+
data Command =
23+
Statement Variable Expression Print
24+
| Pragma Variable Precision Dims
25+
deriving Show
26+
data Precision = MSingle | MDouble
27+
deriving (Show, Eq)
28+
data Print = Output | Silent
29+
deriving (Show, Eq)
30+
type Dims = (Integer, Integer)
31+
type Variable = String
32+
33+
data Expression =
34+
Initialize Initializer Dims -- zeros(n,m) or ones(n,1) or eye(n,n)
35+
| UnaryOp Operator Expression
36+
| BinaryOp Operator Expression Expression
37+
| Variable String
38+
| Scalar Double
39+
deriving Show
40+
data Operator =
41+
Times -- A*B, matrix-matrix or matrix-vector product
42+
| Minus -- A-B, elementwise subtraction
43+
| Plus -- A+B, elementwise addition
44+
| Divide -- A/b, elementwise division
45+
| Transpose -- A', transpose of matrix or vector
46+
deriving Show
47+
data Initializer = Zeros | Ones | Eye | Rand
48+
instance Show Initializer where
49+
show Zeros = "zeros"
50+
show Ones = "ones"
51+
show Eye = "eye"
52+
show Rand = "rand"
53+
54+
expr_parser :: Parser Expression
55+
expr_parser = buildExpressionParser expr_table term <?> "expression"
56+
expr_table = [
57+
[postfix "'" (UnaryOp Transpose)],
58+
[
59+
binary "*" (BinaryOp Times) AssocLeft,
60+
binary "/" (BinaryOp Divide) AssocLeft
61+
],
62+
[
63+
binary "+" (BinaryOp Plus) AssocLeft,
64+
binary "-" (BinaryOp Minus) AssocLeft
65+
] ]
66+
67+
initializer :: Parser Initializer
68+
initializer =
69+
(reserved "zeros" >> return Zeros)
70+
<|> (reserved "ones" >> return Ones)
71+
<|> (reserved "eye" >> return Eye)
72+
<|> (reserved "rand" >> return Rand)
73+
<?> "zeros, ones, eye, rand as initializer"
74+
75+
precision :: Parser Precision
76+
precision =
77+
(reserved "float" >> return MSingle)
78+
<|> (reserved "double" >> return MDouble)
79+
<?> "expected 'float' or 'double' precision"
80+
81+
dims :: Parser Dims
82+
dims = do
83+
args <- parens $ commaSep $ natural
84+
case length args of
85+
1 -> return ((args !! 0), (args !! 0))
86+
2 -> return ((args !! 0), (args !! 1))
87+
_ -> error "shape should be (N) for NxN or (M,N) for MxN"
88+
89+
term :: Parser Expression
90+
term = parens expr_parser
91+
<|> do
92+
i <- initializer
93+
shape <- dims
94+
return $ Initialize i shape
95+
<|> fmap Scalar float
96+
<|> fmap Variable identifier
97+
<?> "variable, initializer, or numeric scalar"
98+
binary op fun assoc = Infix (do { reservedOp op; return fun }) assoc
99+
postfix op fun = Postfix (do { reservedOp op; return fun })
100+
101+
command :: Parser Command
102+
command =
103+
try statement <|> pragma
104+
<?> "expecting statement or type information"
105+
106+
pragma :: Parser Command
107+
pragma = do
108+
v <- identifier
109+
reservedOp "::"
110+
p <- precision
111+
shape <- dims
112+
return $ Pragma v p shape
113+
114+
statement :: Parser Command
115+
statement = do
116+
l <- identifier
117+
reservedOp "="
118+
e <- expr_parser
119+
print <- (semi >> return Silent) <|> (return Output)
120+
return $ Statement l e print
121+
122+
-- IDEA: Make a comment a "statement", inserting it in the outputted file to help
123+
-- annotate it
124+
125+
parser :: Parser TMatlab
126+
parser = do
127+
whiteSpace
128+
ss <- many command
129+
eof
130+
return ss
131+
132+
run_parser :: Stream s Identity t => Parsec s () p -> SourceName -> s -> p
133+
run_parser p fn st = case parse p fn st of
12134
Left error_string -> error ("parse error: " ++ show error_string)
13-
Right parsed -> parsed
135+
Right parsed -> parsed
14136

15-
someFunc :: IO ()
16-
someFunc = putStrLn "someFunc"

0 commit comments

Comments
 (0)