-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexpression.hs
More file actions
80 lines (69 loc) · 4.17 KB
/
expression.hs
File metadata and controls
80 lines (69 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
module Expression where
import PTokenizer
import Data.List
import Debug.Trace
data ExpressionNode = ExpressionValue Token | Expression [ExpressionNode] | ExpressionTokenLiteral [Token] | ExpressionError String | ExpressionRaw ExpressionResult deriving (Eq)
data ExpressionResult = EBool Bool | EInt Int | ETokens [Token] | EString String | EVoid | EError String | ELambda [String] ExpressionNode | EList [ExpressionResult] deriving (Eq)
data Macro = Macro String [String] ExpressionNode Bool deriving(Show)
instance Show ExpressionNode where
show (ExpressionValue v) = show v
show (Expression v) = show v
show (ExpressionError v) = "{ERROR: " ++ v ++ "}"
show (ExpressionTokenLiteral v) = "{TOKENS: " ++ (intercalate " " $ map show v) ++ "}"
show (ExpressionRaw v) = "{VAL: " ++ show v ++ "}"
instance Show ExpressionResult where
show (EBool v) = show v
show (EInt v) = show v
show (ETokens v) = "[" ++ (intercalate " " $ map show v) ++ "]"
show (EList v) = "(" ++ (intercalate ", " $ map show v) ++ ")"
show (EString v) = show v
show (EVoid) = "{VOID}"
show (EError v) = "{ERROR: " ++ v ++ "}"
show (ELambda a b) = "{LAMBDA: " ++ (show b) ++ "}"
readExpression :: [Token] -> (ExpressionNode, [Token])
readExpression (BeginExpression:e) = respondToError x
where
(x, y) = scanExpression e
scanExpression :: [Token] -> ([ExpressionNode], [Token])
scanExpression (BeginExpression:e) = (v : nv, nr)
where
(v, r) = readExpression (BeginExpression:e)
(nv, nr) = scanExpression(r)
scanExpression (EndExpression:r) = ([], r)
scanExpression (TokenLiteralBegin:r) = readTokenLiteral 1 r []
scanExpression [] = (ExpressionError ("Unmatched expression branch at: [" ++ (intercalate [] $ map show e)) : [], [])
scanExpression ((TokenSymbol "true"):r) = ((ExpressionRaw (EBool True)):nv, nr) where (nv, nr) = scanExpression r
scanExpression ((TokenSymbol "false"):r) = ((ExpressionRaw (EBool False)):nv, nr) where (nv, nr) = scanExpression r
scanExpression ((TokenSymbol "void"):r) = ((ExpressionRaw EVoid):nv, nr) where (nv, nr) = scanExpression r
scanExpression (v:r) = (ExpressionValue v : nv, nr)
where
(nv, nr) = scanExpression r
readTokenLiteral :: Int -> [Token] -> [Token] -> ([ExpressionNode], [Token])
readTokenLiteral depth (TokenLiteralBegin:r) buffer = readTokenLiteral (depth + 1) r (buffer ++ [TokenLiteralBegin])
readTokenLiteral 1 (TokenLiteralEnd:r) buffer = (ExpressionTokenLiteral buffer : nv, nr)
where
(nv, nr) = scanExpression r
readTokenLiteral depth (TokenLiteralEnd:r) buffer = readTokenLiteral (depth - 1) r (buffer ++ [TokenLiteralEnd])
readTokenLiteral depth (v:r) buffer = readTokenLiteral depth r (buffer ++ [v])
readTokenLiteral depth [] buffer = ((ExpressionError "Missing end to token literal"):[], [])
respondToError (ExpressionError e:_) = error ("PARSE ERROR: " ++ e)
respondToError (v:r) = respondToError r
respondToError [] = (Expression x, y)
readExpression (x:xr) = (ExpressionError ("Unable to parse expression branch:" ++ show x), xr)
readExpressionLiteral :: [Token] -> ([Token], [Token])
readExpressionLiteral = readExpressionLiteralDepth 0
where
readExpressionLiteralDepth :: Int -> [Token] -> ([Token], [Token])
readExpressionLiteralDepth depth (BeginExpression:r) = ((BeginExpression:next), rem) where (next, rem) = readExpressionLiteralDepth (depth + 1) r
readExpressionLiteralDepth 1 (EndExpression:r) = ((EndExpression:[]), r)
readExpressionLiteralDepth depth (EndExpression:r) = ((EndExpression:next), rem) where (next, rem) = readExpressionLiteralDepth (depth - 1) r
readExpressionLiteralDepth depth (n:r) = (n:next, rem) where (next, rem) = readExpressionLiteralDepth depth r
readExpressionLiteralDepth x y = error ("Wtf: " ++ show x ++ " | " ++ show y)
expressionErrors :: ExpressionNode -> [ExpressionNode]
expressionErrors (ExpressionError v) = [ExpressionError v]
expressionErrors (ExpressionValue v) = []
expressionErrors (Expression v) = intercalate [] $ map expressionErrors v
expressionValid :: ExpressionNode -> Maybe ExpressionNode
expressionValid expr
| (null $ expressionErrors expr) = Just expr
| otherwise = Nothing