summaryrefslogtreecommitdiff
path: root/2-kyu
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-05-11 00:01:17 +0800
committerMistivia <i@mistivia.com>2025-05-11 00:01:17 +0800
commitd19942340cd2e07667c4c0830ac85867e3fcc34e (patch)
treecfa99cfbd8fff21a92ec567edf06815a0647484b /2-kyu
parent808e44d59ba060869720c202ad84b8d4b9ad6aa6 (diff)
stub: assembler-interpreter
Diffstat (limited to '2-kyu')
-rw-r--r--2-kyu/assembler-interpreter.hs165
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"
+
+