{-# LANGUAGE OverloadedStrings #-}
module Mips.Parse.User (
        Data_Section,
        Text_Section,
        Pre_Section ,
        linkParser,
        defineParser,
        functionParser

) where
import Control.Applicative
import Control.Monad
import Data.Attoparsec.Text
import  qualified  Data.ByteString  as  B
import  qualified  Data.Text        as  T

type Data_Section = [String]
type Text_Section = [String]
type Pre_Section  = [String]

newtype  Link     =  Link     String                  deriving  (Show,Eq)
newtype  Define   =  Define   (String,String)         deriving  (Show,Eq)
newtype  Funct    =  Funct    (String,String,String)  deriving  (Show,Eq)
newtype  MString  =  MString  (String,String)         deriving  (Show,Eq)
newtype  MArray   =  MArray   (String,[Int])          deriving  (Show,Eq)
newtype  MInt     =  MInt     (String,Int)            deriving  (Show,Eq)

spaceOrEOL :: Char ->  Bool
spaceOrEOL x = (x == ' ')||(x=='\n')||(x=='\r')

linkParser :: Parser Link
linkParser = do
        string $ "import"
        skipSpace
        file <- takeTill spaceOrEOL
        try $ skipSpace <|> endOfLine
        return $ Link (T.unpack file)

defineParser :: Parser Define
defineParser = do
        string $ "define"
        skipSpace
        name <- takeTill (\x -> (x==' ')||(x=='='))
        try skipSpace
        char '='
        try skipSpace
        value <- takeTill (\x -> (x==' ')||(x=='\n')||(x=='\r'))
        try $ skipSpace <|> endOfLine
        return $ Define (T.unpack name,T.unpack value)

functionParser :: Parser Funct
functionParser = do
        string $ "define"
        skipSpace
        name <- takeTill (\x -> (x==' ')||(x=='('))
        try skipSpace
        char '('
        try skipSpace
        argument <- takeTill (\x -> (x==' ')||(x==')'))
        try skipSpace
        char ')'
        try skipSpace
        char '='
        try skipSpace
        value <- takeTill (\x -> (x==' ')||(x=='\n')||(x=='\r'))
        try $ skipSpace <|> endOfLine
        return $ Funct (T.unpack name,T.unpack argument,T.unpack value)

class UserValue a where
       mipsEq :: a -> String
instance UserValue MInt where
        mipsEq (MInt (s,i)) = s++":"++" .word "++(show i)
instance UserValue MString where
        mipsEq (MString (s0,s1)) = s0++":"++" .ascizz "++("\""++s1++"\"")

getValue :: Parser String
getValue = do
        string $ "val"
        try skipSpace
        name <- takeTill (\x -> (x==' ')||(x=='='))
        try skipSpace
        char '='
        try skipSpace
        return (T.unpack name)


stringParser :: Parser MString
stringParser = do
        name <- getValue
        char '"'
        try skipSpace
        value <- takeTill (\x -> (x=='"'))
        try skipSpace
        char '"'
        try skipSpace <|> endOfLine
        return $ MString (name,T.unpack value)

intParser :: Parser MInt
intParser = do
        name <- getValue
        value <- decimal
        try skipSpace <|> endOfLine
        return $ MInt (name,value)

