-- Copyright (C) 2018-2024 Jun Zhang <zhangjunphy[at]gmail[dot]com>
--
-- This file is a part of decafc.
--
-- decafc is free software: you can redistribute it and/or modify it under the
-- terms of the MIT (X11) License as described in the LICENSE file.
--
-- decafc is distributed in the hope that it will be useful, but WITHOUT ANY
-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-- FOR A PARTICULAR PURPOSE.  See the X11 license for more details.

-- Parser -- Re-export Happy parser functionalities
module Parser
  ( parse,
    Program (..),
    ImportDecl (..),
    FieldDecl (..),
    MethodDecl (..),
    FieldElem (..),
    Type (..),
    Argument (..),
    Block (..),
    Statement (..),
    Location (..),
    AssignExpr (..),
    MethodCall (..),
    ImportArg (..),
    CounterUpdate (..),
    Expr (..),
  )
where

import Data.ByteString.Lazy (ByteString)
import Lexer (Alex (..), Token, runAlex, getAlexState, AlexUserState(..), AlexState(..))
import Parser.Grammar
import Parser.Tree
import Util.SourceLoc as SL
import Data.Text qualified as Text
import Types

parse :: ByteString -> Either [CompileError] Program
parse :: ByteString -> Either [CompileError] Program
parse ByteString
input = case ByteString
-> Alex ([CompileError], Program)
-> Either String ([CompileError], Program)
forall a. ByteString -> Alex a -> Either String a
runAlex ByteString
input Alex ([CompileError], Program)
parseAndHandleError of
        Left String
m -> [CompileError] -> Either [CompileError] Program
forall a b. a -> Either a b
Left [Maybe Range -> Text -> CompileError
CompileError Maybe Range
forall a. Maybe a
Nothing (Text -> CompileError) -> Text -> CompileError
forall a b. (a -> b) -> a -> b
$ String -> Text
Text.pack String
m]
        Right ([CompileError]
errs, Program
_) | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [CompileError] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CompileError]
errs -> [CompileError] -> Either [CompileError] Program
forall a b. a -> Either a b
Left [CompileError]
errs
        Right ([CompileError]
_, Program
program) -> Program -> Either [CompileError] Program
forall a b. b -> Either a b
Right Program
program
  where
    parseAndHandleError :: Alex ([CompileError], Program)
parseAndHandleError = Alex Program
parseInternal Alex Program
-> (Program -> Alex ([CompileError], Program))
-> Alex ([CompileError], Program)
forall a b. Alex a -> (a -> Alex b) -> Alex b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Program
program -> do
      AlexState
state <- Alex AlexState
getAlexState
      let AlexUserState{$sel:errors:AlexUserState :: AlexUserState -> [CompileError]
errors = [CompileError]
errors} = AlexState -> AlexUserState
alex_ust AlexState
state 
      ([CompileError], Program) -> Alex ([CompileError], Program)
forall a. a -> Alex a
forall (m :: * -> *) a. Monad m => a -> m a
return ([CompileError]
errors, Program
program)