diff options
| author | Mistivia <i@mistivia.com> | 2025-05-11 00:01:17 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2025-05-11 00:01:17 +0800 |
| commit | d19942340cd2e07667c4c0830ac85867e3fcc34e (patch) | |
| tree | cfa99cfbd8fff21a92ec567edf06815a0647484b /2-kyu/assembler-interpreter.hs | |
| parent | 808e44d59ba060869720c202ad84b8d4b9ad6aa6 (diff) | |
stub: assembler-interpreter
Diffstat (limited to '2-kyu/assembler-interpreter.hs')
| -rw-r--r-- | 2-kyu/assembler-interpreter.hs | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/2-kyu/assembler-interpreter.hs b/2-kyu/assembler-interpreter.hs new file mode 100644 index 0000000..cf18b68 --- /dev/null +++ b/2-kyu/assembler-interpreter.hs @@ -0,0 +1,165 @@ +module AssemblerInterpreter where + +import Data.Maybe (fromMaybe) +import Text.Parsec +import Text.Parsec.Char + +interpret :: String -> Maybe String +interpret prog = Nothing + +type Parser = Parsec String () + +data Op = + Mov | Inc | Dec | Add | Sub | Mul | Div | Jmp | Cmp | Jne | Je | + Jge | Jg | Jle | Jl | Call | Ret | Msg | End + deriving (Show) + +argsNum Mov = 2 +argsNum Inc = 1 +argsNum Dec = 1 +argsNum Add = 2 +argsNum Sub = 2 +argsNum Mul = 2 +argsNum Div = 2 +argsNum Jmp = 1 +argsNum Cmp = 2 +argsNum Jne = 1 +argsNum Je = 1 +argsNum Jge = 1 +argsNum Jg = 1 +argsNum Jle = 1 +argsNum Jl = 1 +argsNum Call= 1 +argsNum Ret = 0 +argsNum Msg = -1 +argsNum End = 0 + +opStrP :: Parser String +opStrP = choice $ map string' [ + "mov", "inc", "dec", "add", "sub", "mul", "div", "jmp", "cmp", "jne", + "je", "jge", "jg", "jle", "jl", "call", "ret", "msg", "end"] + +opP :: Parser Op +opP = do + s <- opStrP + case s of + "mov" -> return Mov + "inc" -> return Inc + "dec" -> return Dec + "add" -> return Add + "sub" -> return Sub + "mul" -> return Mul + "div" -> return Div + "jmp" -> return Jmp + "cmp" -> return Cmp + "jne" -> return Jne + "je" -> return Je + "jge" -> return Jge + "jg" -> return Jg + "jle" -> return Jle + "jl" -> return Jl + "call"-> return Call + "ret" -> return Ret + "msg" -> return Msg + "end" -> return End + +newtype Label = Label String + deriving (Show) + +inlineSpace :: Parser Char +inlineSpace = oneOf [' ', '\t'] +inlineSpaces = skipMany $ oneOf [' ', '\t'] + +identifierP :: Parser String +identifierP = do + notFollowedBy opStrP + x <- letter <|> oneOf ['_'] + xs <- many (alphaNum <|> oneOf ['_']) + return (x:xs) + +labelP :: Parser Label +labelP = do + id <- identifierP + oneOf [':'] + return $ Label id + +data Stmt = LabelStmt Label | InstrStmt Op [Arg] + deriving (Show) + +data Arg = IdentifierArg String | NumberArg Int | StringArg String + deriving (Show) + +argP :: Parser Arg +argP = do + inlineSpaces + let identifierArgP = IdentifierArg <$> identifierP + numberP = NumberArg . read <$> many1 digit + stringP = do + oneOf ['\''] :: Parser Char + str <- many $ noneOf ['\''] + oneOf ['\''] + return $ StringArg str + arg <- identifierArgP <|> numberP <|> stringP + inlineSpaces + return arg + +stmtP :: Parser Stmt +stmtP = do + let + labelStmtP = LabelStmt <$> labelP + argsP = do + inlineSpaces + oneOf [','] + inlineSpaces + arg <- argP + inlineSpaces + return arg + instrStmtP = do + op <- opP + inlineSpaces + marg <- optionMaybe argP + args <- case marg of + Just arg -> do + targs <- many argsP + return (arg:targs) + Nothing -> return [] + return $ InstrStmt op args + inlineSpaces + stmt <- labelStmtP <|> instrStmtP + inlineSpaces + return stmt + +commentP :: Parser () +commentP = do + oneOf [';'] + many $ noneOf ['\n'] + return () + +stmtLineP :: Parser [Stmt] +stmtLineP = do + inlineSpaces + ms <- optionMaybe stmtP + inlineSpaces + optional commentP + inlineSpaces + case ms of + Just s -> return [s] + Nothing -> return [] + +progP :: Parser [Stmt] +progP = do + let newlineP = do + newline :: Parser Char + return (++) + stmts <- chainl stmtLineP newlineP [] + spaces + return stmts + +main = do + print $ runParser opP () "" "msg" + print $ runParser stmtLineP () "" "ret" + print $ runParser progP () "" "ret \n mov a , 12\n uwu: \n ret" + print $ runParser progP () "" "ret ; 123 ; 123\n mov a , 12\n uwu: \n ret" + print $ runParser progP () "" "\nmov a, 2 ; value1\nmov b, 10 ; value2\nmov c, a ; temp1\nmov d, b ; temp2\ncall proc_func\ncall print\nend\n\nproc_func:\n cmp d, 1\n je continue\n mul c, a\n dec d\n call proc_func\n\ncontinue:\n ret\n\nprint:\n msg a, '^', b, ' = ', c\n ret\n" + + |
