ewe 0.1.0.23 → 0.1.0.30
raw patch · 10 files changed
+262/−96 lines, 10 filesdep +containerssetup-changed
Dependencies added: containers
Files
- Setup.hs +6/−2
- dist/build/ewe/ewe-tmp/Language/EWE/Parser.hs +1/−1
- ewe.cabal +7/−2
- src/Language/EWE/AbsSyn.ag +57/−0
- src/Language/EWE/AbsSyn.hs +0/−69
- src/Language/EWE/CheckGrammar.ag +124/−0
- src/Language/EWE/Parser.y +4/−4
- src/Language/EWE/Utils.hs +27/−0
- src/Language/EWE/VM.hs +17/−13
- src/Main.hs +19/−5
Setup.hs view
@@ -1,2 +1,6 @@-import Distribution.Simple-main = defaultMain+import Distribution.Simple (defaultMainWithHooks)+import Distribution.Simple.UUAGC (uuagcLibUserHook)+import UU.UUAGC(uuagc)++main :: IO ()+main = defaultMainWithHooks (uuagcLibUserHook uuagc)
dist/build/ewe/ewe-tmp/Language/EWE/Parser.hs view
@@ -74,7 +74,7 @@ happyGotoOffsets = HappyA# "\x02\x00\x2c\x00\x45\x00\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x00\x00\x00\x00\x00\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x41\x00\x40\x00\x3f\x00\x3e\x00\x3d\x00\x30\x00\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x39\x00\x00\x00\x38\x00\x37\x00\x35\x00\x2b\x00\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# happyDefActions :: HappyAddr-happyDefActions = HappyA# "\x00\x00\x00\x00\xe3\xff\xfd\xff\xfa\xff\x00\x00\xe0\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xff\xe4\xff\x00\x00\x00\x00\xe0\xff\x00\x00\xe9\xff\xe8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\xff\xfe\xff\x00\x00\x00\x00\xf5\xff\xf9\xff\xf8\xff\x00\x00\x00\x00\xfb\xff\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xda\xff\xdb\xff\xdc\xff\xdd\xff\xde\xff\xdf\xff\x00\x00\xea\xff\x00\x00\xec\xff\xed\xff\xe1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xff\xf1\xff\xf2\xff\xf3\xff\xf4\xff\xf7\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeb\xff\x00\x00\x00\x00\x00\x00\xe3\xff\x00\x00\x00\x00\xe7\xff\xe6\xff\xee\xff\xef\xff\xe2\xff"#+happyDefActions = HappyA# "\x00\x00\x00\x00\xe3\xff\xfd\xff\xfa\xff\x00\x00\xe0\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xff\xe4\xff\x00\x00\x00\x00\xe0\xff\x00\x00\xe9\xff\xe8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\xff\xfe\xff\x00\x00\x00\x00\xf5\xff\xf9\xff\xf8\xff\x00\x00\x00\x00\xfb\xff\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xda\xff\xdb\xff\xde\xff\xdf\xff\xdc\xff\xdd\xff\x00\x00\xea\xff\x00\x00\xec\xff\xed\xff\xe1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xff\xf1\xff\xf2\xff\xf3\xff\xf4\xff\xf7\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeb\xff\x00\x00\x00\x00\x00\x00\xe3\xff\x00\x00\x00\x00\xe7\xff\xe6\xff\xee\xff\xef\xff\xe2\xff"# happyCheck :: HappyAddr happyCheck = HappyA# "\xff\xff\x03\x00\x00\x00\x01\x00\x02\x00\x03\x00\x01\x00\x05\x00\x03\x00\x05\x00\x01\x00\x02\x00\x03\x00\x03\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x04\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x17\x00\x1f\x00\x20\x00\x16\x00\x17\x00\x17\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x01\x00\x02\x00\x03\x00\x05\x00\x05\x00\x01\x00\x02\x00\x03\x00\x05\x00\x05\x00\x02\x00\x03\x00\x01\x00\x05\x00\x03\x00\x01\x00\x06\x00\x03\x00\x05\x00\x21\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x04\x00\x01\x00\x04\x00\x1e\x00\x09\x00\x01\x00\x09\x00\x1c\x00\x07\x00\x01\x00\x0b\x00\x09\x00\x01\x00\x08\x00\x01\x00\x09\x00\x07\x00\x0a\x00\x08\x00\x07\x00\xff\xff\x07\x00\x03\x00\xff\xff\x06\x00\x04\x00\x0b\x00\x0b\x00\x08\x00\x06\x00\x06\x00\x06\x00\x05\x00\x04\x00\x08\x00\xff\xff\xff\xff\x22\x00\xff\xff\xff\xff\x17\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
ewe.cabal view
@@ -2,8 +2,8 @@ -- see http://haskell.org/cabal/users-guide/ name: ewe-version: 0.1.0.23-synopsis: An language to teach a programming+version: 0.1.0.30+synopsis: An language using in Programming Languages teaching description: Another implemention of the EWE programming language originally created and developed by Kent D. Lee. EWE is an extension of the RAM programming language. RAM was created by Sethi. homepage: http://github.com/jfcmacro/ewe license: BSD3@@ -20,14 +20,19 @@ Build-depends: base >=4.5 && < 5, transformers >=0.3, mtl >= 2.1,+ containers >= 0.4.2, array >= 0.4.0.0 hs-source-dirs: src build-tools: alex, happy other-modules: Language.EWE.AbsSyn,+ Language.EWE.Utils, Language.EWE.VM, Language.EWE.Token, Language.EWE.Scanner,+ Language.EWE.CheckGrammar, Language.EWE.Parser+ x-agmodule: file: "src/Language/EWE/AbsSyn.ag" options : data, pretty, haskellsyntax, module "Language.EWE.AbsSyn"+ x-agmodule: file: "src/Language/EWE/CheckGrammar.ag" options : semfuns, pretty, haskellsyntax, catas, wrappers, signatures, module "Language.EWE.CheckGrammar" source-repository head type: git
+ src/Language/EWE/AbsSyn.ag view
@@ -0,0 +1,57 @@++data MRef | MRefI Int+ | MRefId String++deriving MRef : Eq, Show++data Cond | CLET+ | CLT+ | CGET+ | CGT+ | CE+ | CNE++deriving Cond: Eq, Show++type Equ = (String,Int)++type Equates = [Equ]++type Labels = [String]++data Stmt | Stmt labels :: Labels instr :: Instr++deriving Stmt: Eq, Show++type Stmts = [Stmt]++data Prog | Prg stms :: Stmts+ equates :: Equates++deriving Prog : Eq, Show++data Instr | IMMI dest :: MRef Int -- Move a int into memory+ | IMMS dest :: MRef String -- Move a string into memory+ | IMRPC dest :: MRef Int -- Move a relative PC into memory+ | SPC oper :: MRef -- Set PC from memory+ | IMMM dest,oper :: MRef -- Move Memory to Memory+ | IAdd dest,left,right :: MRef -- Add two Memory References+ | ISub dest,left,right :: MRef -- Sub two Memory References+ | IMul dest,left,right :: MRef -- Mul two Memory References+ | IDiv dest,left,right :: MRef -- Div two Memory References+ | IMod dest,left,right :: MRef -- Mod two Memory References+ | IMRI dest,oper :: MRef Int -- Move to Memory Ref+ | IMMR dest :: MRef Int oper :: MRef -- Move to Memory Ref+ | IRI oper :: MRef -- Read an Int into a Mem Ref+ | IWI oper :: MRef -- Write an Int from a Mem Ref+ | IRS left, right :: MRef -- Read a Str+ | IWS oper :: MRef -- Write a Str+ | IGI Int -- Goto to line+ | IGS String -- Goto sym+ | IFI bcond :: MRef Cond then :: MRef Int -- If Cond then Int+ | IFS bcond :: MRef Cond then :: MRef String --+ | IH -- Halt+ | IB -- Break+ | INI++deriving Instr : Eq, Show
− src/Language/EWE/AbsSyn.hs
@@ -1,69 +0,0 @@-module Language.EWE.AbsSyn(MRef(..)- ,Cond(..)- ,Equ- ,Equates- ,Labels- ,Stmt(..)- ,Stmts- ,Prog(..)- ,Instr(..)- ,emptyProg) where--data AbsSyn = Empty--data MRef = MRefI Int- | MRefId String- deriving (Eq, Show)--data Cond = CLET- | CLT- | CGET- | CGT- | CE- | CNE- deriving (Eq,Show)--type Equ = (String,Int)--type Equates = [Equ]--type Labels = [String]--data Stmt = Stmt Labels Instr- deriving (Eq,Show)--type Stmts = [Stmt]--data Prog = Prg {stms :: Stmts- ,equates :: Equates}- deriving (Eq,Show)--data Instr = IMMI MRef Int -- Move Memory Int- | IMMS MRef String -- Move Memory String- | IMRPC MRef Int -- Move Memory Relative PC- | SPC MRef -- Set PC- | IMMM MRef MRef -- Move Memory to Memory- | IAdd MRef MRef MRef -- Add two Memory References- | ISub MRef MRef MRef -- Sub two Memory References- | IMul MRef MRef MRef -- Mul two Memory References- | IDiv MRef MRef MRef -- Div two Memory References- | IMod MRef MRef MRef -- Mod two Memory References- | IMRI MRef MRef Int -- Move to Memory ref a Indexed Memory Pos- | IMMR MRef Int MRef -- Move to Index Memory Ref a Memory Ref- | IRI MRef -- Read an Int and stored into a Mem Ref- | IWI MRef -- Write an Int from a Mem Ref- | IRS MRef MRef -- Read a Str- | IWS MRef -- Write a Str- | IGI Int -- Goto to line- | IGS String -- Goto sym- | IFI MRef Cond MRef Int -- If Cond then Int- | IFS MRef Cond MRef String --- | IH -- Halt- | IB -- Break- | INI- deriving (Eq,Show)--emptyProg :: Prog-emptyProg = Prg { stms = []- , equates = []- }
+ src/Language/EWE/CheckGrammar.ag view
@@ -0,0 +1,124 @@+imports+{+import qualified Data.Set as Set+import qualified Data.Map as Map+import Language.EWE.AbsSyn+import Language.EWE.Utils+}++attr Prog+ syn res :: {Either String ()}++attr Equates+ chn idMemRef :: {Map.Map String Int}++attr Equ+ chn idMemRef :: {Map.Map String Int}+ syn res :: {Either String ()}++attr Stmts+ chn labelDef :: {Set.Set String}+ inh labelFound :: {Set.Set String}+ inh idMemRefDef :: {Map.Map String Int}+ syn res use {(<-->)} {Right ()} :: {Either String ()}++attr Stmt+ chn labelDef :: {Set.Set String}+ inh labelFound :: {Set.Set String}+ inh idMemRefDef :: {Map.Map String Int}+ syn res :: {Either String ()}++attr Instr+ inh labelFound :: {Set.Set String}+ inh idMemRefDef :: {Map.Map String Int}+ syn res :: {Either String ()}++attr Labels+ syn res :: { Either String () }+ chn labelDef :: { Set.Set String }+ syn copy :: self++attr MRef+ inh idMemRefDef :: { Map.Map String Int }+ syn res :: { Either String () }++sem Equ+ | Tuple lhs.res = { if @x1 `Map.member` @lhs.idMemRef+ then Left $ @x1 ++ " was already defined "+ else Right ()+ }+ .idMemRef = { Map.insert @x1 @x2 @lhs.idMemRef }++sem Labels+ | Cons lhs.res = { isLabelNotDef @hd @tl.labelDef }+ .labelDef = { Set.insert @hd @tl.labelDef }+ | Nil lhs.res = { Right () }+ .labelDef = { @lhs.labelDef }++sem Prog+ | Prg stms.labelDef = { Set.empty }+ .labelFound = { @stms.labelDef }+ .idMemRefDef = { @equates.idMemRef }+ equates.idMemRef = { Map.empty }++sem Stmt+ | Stmt loc.res1 = {+ let f (e,er,s) lbl = if Set.member lbl s+ then (True,+ lbl ++ " is already defined\n" ++ er,+ s)+ else (e, er, Set.insert lbl s)+ (e', errs', set') = foldl f (False,"",@lhs.labelDef) @labels.copy+ in if e'+ then Left errs'+ else Right ()+ }+ lhs.res = { @res1 <--> @instr.res }++sem MRef+ | MRefI lhs.res = Right ()+ | MRefId lhs.res = isMemRefDef @string @lhs.idMemRefDef++sem Instr+ | IMMI lhs.res = { @dest.res }+ | IMMS lhs.res = { @dest.res }+ | IMRPC lhs.res = { @dest.res }+ | SPC lhs.res = { @oper.res }+ | IMMM lhs.res = { @dest.res <--> @oper.res }+ | IAdd lhs.res = { @dest.res <--> @left.res <--> @right.res }+ | ISub lhs.res = { @dest.res <--> @left.res <--> @right.res }+ | IMul lhs.res = { @dest.res <--> @left.res <--> @right.res }+ | IDiv lhs.res = { @dest.res <--> @left.res <--> @right.res }+ | IMod lhs.res = { @dest.res <--> @left.res <--> @right.res }+ | IMRI lhs.res = { @dest.res <--> @oper.res }+ | IMMR lhs.res = { @dest.res <--> @oper.res }+ | IRI lhs.res = { @oper.res }+ | IWI lhs.res = { @oper.res }+ | IRS lhs.res = { @left.res <--> @right.res }+ | IWS lhs.res = { @oper.res }+ | IGI lhs.res = { Right () }+ | IGS lhs.res = { isLabelDef @string @lhs.labelFound }+ | IFI lhs.res = { @bcond.res <--> @then.res }+ | IFS lhs.res = { isLabelDef @string @lhs.labelFound <--> @bcond.res <--> @then.res}+ | IH lhs.res = { Right () }+ | IB lhs.res = { Right () }+ | INI lhs.res = { Right () }++include "AbsSyn.ag"++{+isLabelDef :: String -> Set.Set String -> Either String ()+isLabelDef str sets+ | str `Set.member` sets = Right ()+ | otherwise = Left $ "Label: " ++ str ++ " is not defined "++isLabelNotDef :: String -> Set.Set String -> Either String ()+isLabelNotDef str sets+ | str `Set.member` sets = Left $ "Label: " ++ str ++ " is already defined "+ | otherwise = Right ()++isMemRefDef :: String -> Map.Map String Int -> Either String ()+isMemRefDef str map+ | str `Map.member` map = Right ()+ | otherwise = Left $ "Mem Ref: " ++ str ++ " is not defined"+}
src/Language/EWE/Parser.y view
@@ -86,10 +86,10 @@ MemRef : 'M' '[' int ']' { MRefI $3 } | id { MRefId $1 } -Cond : '>=' { CLET }- | '>' { CLT }- | '<=' { CGET }- | '<' { CGT }+Cond : '<=' { CLET }+ | '<' { CLT }+ | '>=' { CGET }+ | '>' { CGT } | '=' { CE } | '<>' { CNE }
+ src/Language/EWE/Utils.hs view
@@ -0,0 +1,27 @@+module Language.EWE.Utils(emptyProg,+ equates,+ stms,+ (<-->),+ isMemRefId) where++import Language.EWE.AbsSyn++emptyProg :: Prog+emptyProg = Prg [] []++equates :: Prog -> Equates+equates (Prg _ e) = e++stms :: Prog -> Stmts+stms (Prg s _) = s++infixl 5 <-->++(<-->) :: Either String () -> Either String () -> Either String ()+(Left s) <--> (Left s') = Left (s ++ "\n" ++ s')+(Left s) <--> _ = Left s+_ <--> (Left s') = Left s'+_ <--> a = a++isMemRefId :: MRef -> Bool+isMemRefId (MRefId _) = True
src/Language/EWE/VM.hs view
@@ -2,6 +2,7 @@ module Language.EWE.VM(runVM,execVM) where import Language.EWE.AbsSyn+import Language.EWE.Utils(emptyProg, equates, stms) import qualified Data.List as L import qualified Data.Maybe as M import Control.Monad.Trans.State.Lazy@@ -32,7 +33,7 @@ type StateVMM = StateT StateVM IO -runVM :: Prog -> IO () +runVM :: Prog -> IO () runVM prg = evalStateT evalVM (initVM prg) execVM :: Prog -> IO StateVM@@ -42,13 +43,13 @@ evalVM = do lift $ hPutStrLn stdout "Iniciando maquina" evalInstr- + initVM :: Prog -> StateVM initVM p = emptyStateVM { prg = p } mRef :: MRef -> Equates -> Int mRef (MRefI i) _ = i-mRef (MRefId s) m = M.fromMaybe (error "No found") $ L.lookup s m+mRef (MRefId s) m = M.fromMaybe (error $ "Internal error: memory reference " ++ s ++ " not found ") $ L.lookup s m outMem :: Int -> Memory -> (Memory,Int) outMem r m = M.maybe ((r,0):m, 0) (\i -> (m,i)) (L.lookup r m)@@ -107,9 +108,12 @@ state { mem = inMem (mRef mr (ge state)) i (mem state) , pc = incrPC state }-execInstr (IMMS mr s) state =- state { mem = inMem (mRef mr (ge state)) (mRef (MRefId s) (ge state)) (mem state)- , pc = incrPC state+execInstr (IMMS mr s) st = + let base = mRef mr (ge st)+ total = base + length s+ st' = moveStrInMem s base total st+ in st { mem = mem st'+ , pc = incrPC st } execInstr (IMRPC mr i) state = state { mem = inMem (mRef mr (ge state)) ((pc state) + i) (mem state)@@ -125,9 +129,9 @@ in state { mem = inMem (mRef mr1 ge') v m' , pc = incrPC state }-execInstr (IAdd mrr mra mrb) state = comp (+) mrr mra mrb state-execInstr (ISub mrr mra mrb) state = comp (-) mrr mra mrb state-execInstr (IMul mrr mra mrb) state = comp (*) mrr mra mrb state+execInstr (IAdd mrr mra mrb) state = comp (+) mrr mra mrb state+execInstr (ISub mrr mra mrb) state = comp (-) mrr mra mrb state+execInstr (IMul mrr mra mrb) state = comp (*) mrr mra mrb state execInstr (IDiv mrr mra mrb) state = comp (div) mrr mra mrb state execInstr (IMod mrr mra mrb) state = comp (mod) mrr mra mrb state execInstr (IMRI mrr mr i) state =@@ -166,7 +170,7 @@ stms' = stms prg' l' = length stms' (m',a) = outMem (mRef mra ge') m- (m'',b) = outMem (mRef mra ge') m'+ (m'',b) = outMem (mRef mrb ge') m' op = fun cond i' = if (i >= 0 && i < l') then i else error "Inst Pos not valid in condition"@@ -182,7 +186,7 @@ stms' = stms prg' l' = length stms' (m',a) = outMem (mRef mra ge') m- (m'',b) = outMem (mRef mra ge') m'+ (m'',b) = outMem (mRef mrb ge') m' op = fun cond i = lookupLabel s stms' npc = if a `op` b then i else pc' + 1@@ -244,8 +248,8 @@ lookupLabel' n s [] = error "Label not found" lookupLabel' n s ((Stmt [] _):stms) = lookupLabel' (n+1) s stms lookupLabel' n s ((Stmt lbls _):stms)- | s `elem` lbls = n- | otherwise = lookupLabel' (n+1) s stms+ | s `elem` lbls = n+ | otherwise = lookupLabel' (n+1) s stms fun :: Cond -> (Int -> Int -> Bool) fun CLET = (<=)
src/Main.hs view
@@ -14,6 +14,7 @@ import Language.EWE.Parser import Language.EWE.AbsSyn import Language.EWE.VM(runVM,execVM)+import Language.EWE.CheckGrammar data Options = Options { optShowVersion :: Bool , optNoExec :: Bool@@ -30,7 +31,7 @@ options :: [OptDescr (Options -> Options)] options =- [ Option ['V','?'] ["version"]+ [ Option ['v','?'] ["version"] (NoArg (\opts -> opts { optShowVersion = True })) "show version number" , Option ['n'] ["noexec"]@@ -77,12 +78,25 @@ s <- hGetContents fh let scanout = runAlex s alexExec pRes = pEWE s- errorParser = either (\_ -> True) (\_ -> False) pRes- when (optScanOut opts) (showScannerOutput scanout)- when (optParserOut opts) (showParserOutput pRes)- when (optNoExec opts) (execProg errorParser pRes)+ errorParser = either (\_ -> True) (\_ -> False) pRes+ (passGrammar,errGram) = either (\_ -> (False,[])) checkGrammar pRes+ when (optScanOut opts) (showScannerOutput scanout)+ when (optParserOut opts) (showParserOutput pRes)+ when (not passGrammar) (showErrorGrammar errGram)+ when (optNoExec opts && passGrammar) (execProg errorParser pRes) hClose fh +showErrorGrammar :: String -> IO ()+showErrorGrammar msg = do+ hPutStrLn stderr $ show msg++checkGrammar :: Prog -> (Bool,String)+checkGrammar prog = let inh = Inh_Prog+ syn = wrap_Prog (sem_Prog prog) inh+ in case (res_Syn_Prog syn) of+ Left msg -> (False, msg)+ Right () -> (True, [])+ processStaticOptions :: Options -> IO () processStaticOptions opts = if optShowVersion opts