Changeset 31
- Timestamp:
- 02/16/05 15:20:15 (4 years ago)
- svk:copy_cache_prev:
- 1041
- Files:
-
- 10 modified
-
src/AST.hs (modified) (4 diffs)
-
src/Context.hs (modified) (1 diff)
-
src/Eval.hs (modified) (14 diffs)
-
src/Lexer.hs (modified) (3 diffs)
-
src/Main.hs (modified) (1 diff)
-
src/Monads.hs (modified) (10 diffs)
-
src/Parser.hs (modified) (10 diffs)
-
src/Pretty.hs (modified) (1 diff)
-
src/Prim.hs (modified) (1 diff)
-
t/01basic.t (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/AST.hs
r29 r31 266 266 = App String [Exp] [Exp] 267 267 | Syn String [Exp] 268 | Sym S cope Var268 | Sym Symbol 269 269 | Prim ([Val] -> Eval Val) 270 270 | Val Val 271 | Var Var SourcePos271 | Var Var 272 272 | Parens Exp 273 273 | NonTerm SourcePos … … 287 287 where 288 288 (exps', vs') = foldr extractExp ([], vs) exps 289 extract ((Var name pos), vs)289 extract ((Var name), vs) 290 290 | (sigil:'^':identifer) <- name 291 291 , name' <- (sigil : identifer) 292 = (Var name' pos, insert name' vs)292 = (Var name', insert name' vs) 293 293 | name == "$_" 294 = (Var name pos, insert name vs)294 = (Var name, insert name vs) 295 295 | otherwise 296 = (Var name pos, vs)296 = (Var name, vs) 297 297 extract ((Parens exp), vs) = ((Parens exp'), vs') 298 298 where … … 327 327 328 328 data Env = Env { envContext :: Cxt 329 , envPad :: Pad 329 , envLexical :: Pad 330 , envGlobal :: Pad 330 331 , envClasses :: ClassTree 331 332 , envEval :: Exp -> Eval Val … … 341 342 data Symbol = Symbol { symScope :: Scope 342 343 , symName :: String 343 , sym Value :: Val344 , symExp :: Exp 344 345 } deriving (Show, Eq, Ord) 345 346 -
src/Context.hs
r29 r31 99 99 [ Node "Class" [] ] ] 100 100 , Node "Action" [] 101 , Node "Void" [] 101 102 ] -
src/Eval.hs
r29 r31 30 30 return $ Env 31 31 { envContext = "List" 32 , envPad = initSyms 32 , envLexical = [] 33 , envGlobal = initSyms 33 34 , envClasses = initTree 34 35 , envEval = evaluate … … 56 57 evaluate :: Exp -> Eval Val 57 58 evaluate (Val (VSub sub)) = do 58 pad <- asks env Pad59 pad <- asks envLexical 59 60 return $ VSub sub{ subPad = pad } -- closure! 60 61 evaluate (Val val) = return val … … 72 73 evl exp 73 74 75 evalSym :: Symbol -> Eval (String, Val) 76 evalSym (Symbol _ name vexp) = do 77 val <- evalExp vexp 78 return (name, val) 79 74 80 enterEvalContext cxt = enterContext cxt . evalExp 75 81 … … 80 86 env@Env{ envBody = body } <- ask 81 87 doReduce env body 88 89 reduceExp :: Exp -> Eval Exp 90 reduceExp exp = do 91 env <- ask 92 doReduce env exp 82 93 83 94 retVal :: Val -> Eval Exp … … 90 101 retVal val 91 102 reduceStatements (exp:rest) 92 | Syn syn [Var var _, exp'] <- exp 103 | Syn "sym" [Sym sym@(Symbol SGlobal _ _)] <- exp = do 104 local (\e -> e{ envGlobal = (sym:envGlobal e) }) $ do 105 reduceStatements rest 106 | Syn "sym" [Sym sym@(Symbol SMy _ _)] <- exp = do 107 enterLex [sym] $ do 108 reduceStatements rest 109 | Syn syn [Var name, exp'] <- exp 93 110 , (syn == ":=" || syn == "::=") = do 94 val <- enterContext (cxtOfSigil $ head var) (evalExp exp) 95 processVal val $ do 96 enterLex [Symbol SMy var val] $ reduceStatements rest 111 lex <- asks envLexical 112 case findSym name lex of 113 Just _ -> do 114 let sym = (Symbol SMy name exp') 115 enterLex [sym] $ do 116 reduceStatements rest 117 Nothing -> do 118 let sym = (Symbol SGlobal name exp') 119 local (\e -> e{ envGlobal = (sym:envGlobal e) }) $ do 120 reduceStatements rest 97 121 | otherwise = do 98 val <- enterContext " Any" $ evalExp exp122 val <- enterContext "Void" $ evalExp exp 99 123 processVal val $ do 100 124 reduceStatements rest … … 107 131 108 132 -- Reduction for variables 109 doReduce Env{ envPad = pad } exp@(Var var _) 110 | Just val <- findSym var pad 111 = retVal val 112 | Just val <- findSym (toGlobal var) pad 113 = retVal val 133 doReduce Env{ envLexical = lex, envGlobal = glob } exp@(Var var) 134 | Just vexp <- findSym var lex 135 = reduceExp vexp 136 | Just vexp <- findSym var glob 137 = reduceExp vexp 138 | Just vexp <- findSym (toGlobal var) glob 139 = reduceExp vexp 114 140 | otherwise 115 141 = retVal $ VError ("Undefined variable " ++ var) exp … … 120 146 let (global, local) = partition isGlobalExp exps 121 147 reduceStatements (global ++ local) 148 "sym" -> do 149 let [Sym (Symbol _ _ exp)] = exps 150 val <- evalExp exp 151 retVal val 122 152 ":=" -> do 123 let [Var var _, exp] = exps153 let [Var var, exp] = exps 124 154 val <- evalExp exp 125 155 retVal val 126 156 "::=" -> do -- XXX wrong 127 let [Var var _, exp] = exps157 let [Var var, exp] = exps 128 158 val <- evalExp exp 129 159 retVal VUndef -- XXX wrong … … 159 189 doSlice _ _ _ = Nothing 160 190 161 doReduce env@Env{ envClasses = cls, envContext = cxt, envPad = pad } exp@(App name invs args) = do 162 case findSub name of 163 Just sub -> applySub sub invs args 191 doReduce env@Env{ envClasses = cls, envContext = cxt, envLexical = lex, envGlobal = glob } exp@(App name invs args) = do 192 subSyms <- mapM evalSym [ sym | sym <- lex ++ glob, head (symName sym) == '&' ] 193 case findSub subSyms name of 194 Just sub -> applySub subSyms sub invs args 164 195 otherwise -> retVal $ VError ("No compatible subroutine found: " ++ name) exp 165 196 where 166 applySub sub invs args197 applySub subSyms sub invs args 167 198 -- list-associativity 168 199 | Sub{ subAssoc = "list" } <- sub … … 170 201 , name == name' 171 202 , null invs' 172 = applySub sub [] (args' ++ rest)203 = applySub subSyms sub [] (args' ++ rest) 173 204 -- fix subParams to agree with number of actual arguments 174 205 | Sub{ subAssoc = "list", subParams = (p:_) } <- sub … … 178 209 | Sub{ subAssoc = "chain", subFun = fun, subParams = prm } <- sub 179 210 , (App name' invs' args'):rest <- args 180 , Just sub' <- findSub name'211 , Just sub' <- findSub subSyms name' 181 212 , Sub{ subAssoc = "chain", subFun = fun', subParams = prm' } <- sub' 182 213 , null invs' 183 = applySub sub { subParams = prm ++ tail prm', subFun = Prim $ chainFun prm' fun' prm fun } [] (args' ++ rest)214 = applySub subSyms sub{ subParams = prm ++ tail prm', subFun = Prim $ chainFun prm' fun' prm fun } [] (args' ++ rest) 184 215 -- fix subParams to agree with number of actual arguments 185 216 | Sub{ subAssoc = "chain", subParams = (p:_) } <- sub … … 189 220 | otherwise 190 221 = apply sub invs args 191 findSub name192 | ((_, sub):_) <- sort (subs name) =Just sub193 | otherwise =Nothing194 subs name = [222 findSub subSyms name = case sort (subs subSyms name) of 223 ((_, sub):_) -> Just sub 224 _ -> Nothing 225 subs subSyms name = [ 195 226 ( (isGlobal, subT, isMulti sub, bound, distance, order) 196 227 , fromJust fun 197 228 ) 198 | (( Symbol _ n val), order) <- pad`zip` [0..]229 | ((n, val), order) <- subSyms `zip` [0..] 199 230 , let sub@(Sub{ subType = subT, subReturns = ret, subParams = prms }) = vCast val 200 231 , (n ==) `any` [name, toGlobal name] … … 237 268 where 238 269 formal = filter (not . null . symName) $ map argNameValue bound 239 argNameValue (ApplyArg name val _) = Symbol SMy name val270 argNameValue (ApplyArg name val _) = Symbol SMy name (Val val) 240 271 241 272 apply :: VSub -> [Exp] -> [Exp] -> Eval Exp … … 263 294 let name = paramName prm 264 295 arg = ApplyArg name val coll 265 restArgs <- enterLex [Symbol SMy name val] $ do296 restArgs <- enterLex [Symbol SMy name (Val val)] $ do 266 297 doBind rest 267 298 return (arg:restArgs) … … 281 312 | otherwise = name 282 313 283 isGlobalExp (Syn name _) = name `elem` (words ": = ::=")314 isGlobalExp (Syn name _) = name `elem` (words "::=") 284 315 isGlobalExp _ = False 285 316 286 findSym :: String -> Pad -> Maybe Val317 findSym :: String -> Pad -> Maybe Exp 287 318 findSym name pad 288 319 | Just s <- find ((== name) . symName) pad 289 = Just $ sym Values320 = Just $ symExp s 290 321 | otherwise 291 322 = Nothing -
src/Lexer.hs
r29 r31 153 153 154 154 ruleScope :: RuleParser Scope 155 ruleScope = postSpace $ try$ do155 ruleScope = tryRule "scope" $ do 156 156 scope <- choice $ map symbol scopes 157 157 return (readScope scope) … … 165 165 = SGlobal 166 166 167 preSpace rule = try $ do168 skipMany1 (satisfy isSpace)169 rule170 171 167 postSpace rule = try $ do 172 168 rv <- rule 173 choice [skipMany1 (satisfy isSpace), eof <?> ""] 169 notFollowedBy wordAny 170 whiteSpace 174 171 return rv 175 172 … … 195 192 return $ (sigil:caret) ++ name 196 193 194 tryChoice = choice . map try -
src/Main.hs
r29 r31 75 75 f val 76 76 where 77 prepare e = e{ env Pad=78 [ Symbol SGlobal "@*ARGS" (V List $ map VStr args)79 , Symbol SGlobal "$*PROGNAME" (V Str name)80 ] ++ env Pade }77 prepare e = e{ envGlobal = 78 [ Symbol SGlobal "@*ARGS" (Val $ VList $ map VStr args) 79 , Symbol SGlobal "$*PROGNAME" (Val $ VStr name) 80 ] ++ envGlobal e } 81 81 -
src/Monads.hs
r29 r31 16 16 17 17 enterLex :: Pad -> Eval a -> Eval a 18 enterLex pad = local (\e -> e{ env Pad = (pad ++ envPade) })18 enterLex pad = local (\e -> e{ envLexical = (pad ++ envLexical e) }) 19 19 20 20 enterContext :: Cxt -> Eval a -> Eval a … … 23 23 main = do 24 24 uniq <- newUnique 25 x <- (`runReaderT` env{ envID = uniq }) $ do25 x <- (`runReaderT` testEnv{ envID = uniq }) $ do 26 26 y <- (`runContT` return) $ blah 27 27 return y … … 29 29 return x 30 30 31 env = Env { envContext = "List" 32 , envPad = [] 31 testEnv = Env { envContext = "List" 32 , envLexical = [] 33 , envGlobal = [] 33 34 , envCaller = Nothing 34 35 , envClasses = initTree … … 67 68 68 69 enterSub sub@Sub{ subType = typ } action 69 | typ > SubRoutine= action70 | typ >= SubPrim = action 70 71 | otherwise = do 71 72 cxt <- asks envContext 72 73 resetT $ do 73 local (\e -> e{ env Pad= (ret cxt:subPad sub) }) $ do74 local (\e -> e{ envLexical = (ret cxt:subPad sub) }) $ do 74 75 action 75 76 where 76 77 doReturn [v] = do 77 78 shiftT $ \_ -> return v 78 ret cxt = Symbol SMy "&prefix:return" (V Sub $ retSub cxt)79 ret cxt = Symbol SMy "&prefix:return" (Val $ VSub $ retSub cxt) 79 80 retSub cxt = Sub 80 81 { isMulti = False … … 98 99 {- 99 100 enterSub sub = enterScope $ do 100 local (\e -> e { env Pad= subPad sub }) $ do101 local (\e -> e { envLexical = subPad sub }) $ do 101 102 case subName sub of 102 103 "inner" -> inner … … 108 109 , subName = "inner" 109 110 , subType = SubRoutine 110 , subPad = [Symbol SMy "$inner" VUndef]111 , subPad = [Symbol SMy "$inner" (Val VUndef)] 111 112 , subAssoc = "left" 112 113 , subParams = [] … … 119 120 , subName = "sub3" 120 121 , subType = SubRoutine 121 , subPad = [Symbol SMy "$inner" VUndef]122 , subPad = [Symbol SMy "$inner" (Val VUndef)] 122 123 , subAssoc = "left" 123 124 , subParams = [] … … 130 131 dumpLex :: String -> Eval () 131 132 dumpLex label = do 132 pad <- asks env Pad133 pad <- asks envLexical 133 134 depth <- asks envDepth 134 135 liftIO $ putStrLn ("("++(show depth)++")"++label ++ ": " ++ (show pad)) … … 138 139 blah = do 139 140 dumpLex ">init" 140 rv <- enterLex [Symbol SMy "$x" $ V Int 1] $ do141 rv <- enterLex [Symbol SMy "$x" $ Val $ VInt 1] $ do 141 142 dumpLex ">lex" 142 143 rv <- enterScope outer … … 147 148 148 149 outer :: Eval Val 149 outer = enterLex [Symbol SMy "$outer" $ V Int 2] $ do150 outer = enterLex [Symbol SMy "$outer" $ Val $ VInt 2] $ do 150 151 dumpLex ">outer" 151 152 -- enterSub innerSub -
src/Parser.hs
r29 r31 22 22 many (symbol ";") 23 23 statements <- option [] ruleStatementList 24 many (symbol ";") 24 25 eof 25 26 env <- getState … … 31 32 many (symbol ";") 32 33 statements <- option [] ruleStatementList 34 many (symbol ";") 33 35 retSyn ";" statements 34 36 … … 44 46 doSep count rule = do 45 47 statement <- rule 46 rest <- option [] $ do { count (symbol ";"); ruleStatementList }48 rest <- option [] $ try $ do { count (symbol ";"); ruleStatementList } 47 49 return (statement:rest) 48 50 … … 53 55 [ ruleSubDeclaration 54 56 , rulePackageDeclaration 55 ] 57 , ruleVarDeclaration 58 ] 59 60 ruleSubHead :: RuleParser (Bool, String) 61 ruleSubHead = rule "subroutine head" $ do 62 multi <- option False $ do { symbol "multi" ; return True } 63 symbol "sub" 64 name <- ruleSubName 65 return (multi, name) 66 67 ruleSubScopedWithContext = rule "scoped subroutine with context" $ do 68 scope <- ruleScope 69 cxt <- identifier 70 (multi, name) <- ruleSubHead 71 return (scope, cxt, multi, name) 72 73 ruleSubScoped = rule "scoped subroutine" $ do 74 scope <- ruleScope 75 (multi, name) <- ruleSubHead 76 return (scope, "Any", multi, name) 77 78 ruleSubGlobal = rule "global subroutine" $ do 79 (multi, name) <- ruleSubHead 80 return (SGlobal, "Any", multi, name) 56 81 57 82 ruleSubDeclaration :: RuleParser Exp 58 83 ruleSubDeclaration = rule "subroutine declaration" $ do 59 (scope, multi, name) <- try $ do 60 scope <- option SGlobal $ ruleScope 61 multi <- option False $ do { symbol "multi" ; return True } 62 symbol "sub" 63 name <- ruleSubName 64 return (scope, multi, name) 84 (scope, cxt1, multi, name) <- tryChoice 85 [ ruleSubScopedWithContext 86 , ruleSubScoped 87 , ruleSubGlobal 88 ] 65 89 pos <- getPosition 66 cxt <- option "Any"$ ruleBareTrait "returns"90 cxt2 <- option cxt1 $ ruleBareTrait "returns" 67 91 formal <- option Nothing $ return . Just =<< parens ruleSubParameters 68 92 body <- ruleBlock … … 77 101 , subType = SubRoutine 78 102 , subAssoc = "pre" 79 , subReturns = cxt 103 , subReturns = cxt2 80 104 , subParams = if null params then [defaultArrayParam] else params 81 105 , subFun = fun 82 106 } 83 107 -- XXX: user-defined infix operator 84 return $ Syn " :=" [Var name pos, Val (VSub sub)]108 return $ Syn "sym" [Sym $ Symbol scope name (Val $ VSub sub)] 85 109 86 110 ruleSubName = rule "subroutine name" $ do … … 120 144 ruleExpression 121 145 146 ruleVarDeclaration :: RuleParser Exp 147 ruleVarDeclaration = rule "variable declaration" $ do 148 scope <- ruleScope 149 name <- parseVarName 150 return $ Syn "sym" [Sym (Symbol scope name (Val VUndef))] 151 122 152 rulePackageDeclaration = rule "package declaration" $ fail "" 123 153 124 154 -- Constructs ------------------------------------------------ 125 155 126 ruleConstruct = rule "construct" $ choice156 ruleConstruct = rule "construct" $ tryChoice 127 157 [ ruleGatherConstruct 158 , ruleBlockConstruct 128 159 ] 129 160 130 161 ruleGatherConstruct = rule "gather construct" $ do 131 162 symbol "gather" 132 block <- ruleBlock163 block <- ruleBlock 133 164 retSyn "gather" [block] 134 165 135 -- XXX not sure how many of these can be rolled into Prim 136 ruleBlockConstruct = rule "block construct" $ fail "" 166 ruleBlockConstruct = rule "block construct" $ do 167 formal <- option Nothing $ choice [ ruleBlockFormalStandard, ruleBlockFormalPointy ] 168 block <- ruleBlock 169 fail "" 170 171 ruleBlockFormalStandard = rule "standard block parameters" $ do 172 symbol "sub" 173 return . Just =<< parens ruleSubParameters 174 175 ruleBlockFormalPointy = rule "pointy block parameters" $ do 176 symbol "->" 177 return . Just =<< ruleSubParameters 178 137 179 ruleCondConstruct = rule "conditional construct" $ fail "" 138 180 ruleLoopConstruct = rule "loop construct" $ fail "" … … 306 348 307 349 parseVar = do 308 pos <- getPosition309 350 name <- parseVarName 310 return $ Var name pos351 return $ Var name 311 352 312 353 nonTerm = do … … 322 363 , namedLiteral "NaN" (VNum $ 0/0) 323 364 , namedLiteral "Inf" (VNum $ 1/0) 365 , dotdotdotLiteral 324 366 ] 325 367 … … 343 385 344 386 namedLiteral n v = do { symbol n; return $ Val v } 387 388 dotdotdotLiteral = do 389 pos <- getPosition 390 symbol "..." 391 return . Val $ VError "..." (NonTerm pos) 345 392 346 393 op_methodPostfix = [] … … 358 405 where 359 406 progName 360 | Just Symbol{ sym Value = (VStr str) } <- find ((== "$*PROGNAME") . symName) $ envPadenv407 | Just Symbol{ symExp = Val (VStr str) } <- find ((== "$*PROGNAME") . symName) $ envGlobal env 361 408 = str 362 409 | otherwise -
src/Pretty.hs
r29 r31 46 46 JNone -> " ! " 47 47 pretty (VPair x y) = "(" ++ pretty x ++ " => " ++ pretty y ++ ")" 48 pretty (VBool x) = if x then " #t" else "#f"48 pretty (VBool x) = if x then "bool::true" else "bool::false" 49 49 pretty (VNum x) = if x == 1/0 then "Inf" else show x 50 50 pretty (VInt x) = show x -
src/Prim.hs
r29 r31 196 196 197 197 primOp :: String -> String -> Params -> String -> Symbol 198 primOp sym assoc prms ret = Symbol SOur name sub198 primOp sym assoc prms ret = Symbol SOur name (Val sub) 199 199 where 200 200 name = '&':'*':fixity ++ ':':sym -
t/01basic.t
r30 r31 12 12 open PUGS, "| $pugs" or die "Cannot pipe out to $pugs: $!"; 13 13 print PUGS << '.'; 14 sub cool { fine($_) ~ " # We've got " ~ toys }; 14 15 sub fine { "ok " ~ $_ }; 15 16 sub toys { "fun and games!\n" }; 16 sub cool { fine($_) ~ " # We've got " ~ toys };17 17 cool 2 18 18 .
