packages feed

vintage-basic-1.0: src/Language/VintageBasic/Syntax.hs

-- | Describes the abstract syntax of BASIC.

module Language.VintageBasic.Syntax where

import Language.VintageBasic.Builtins(Builtin)
import Language.VintageBasic.LexCommon(Tagged(..))

-- | A BASIC line number.
type Label = Int

-- | BASIC value types. The IntType is used for storage or function arguments
-- but is always converted to FloatType for use in expressions.
data ValType = FloatType | IntType | StringType
    deriving (Show,Eq)

class Typeable a where
    typeOf :: a -> ValType

instance Typeable ValType where
    typeOf = id

data Literal =
    FloatLit Float
  | StringLit String
    deriving (Show,Eq)

instance Typeable Literal where
    typeOf (FloatLit  _) = FloatType
    typeOf (StringLit _) = StringType

data VarName = VarName ValType String
    deriving (Show,Eq)

instance Typeable VarName where
    typeOf (VarName valType _) = valType

data Var = ScalarVar VarName | ArrVar VarName [Expr]
    deriving (Show,Eq)

instance Typeable Var where
    typeOf (ScalarVar varName) = typeOf varName
    typeOf (ArrVar varName _)  = typeOf varName

-- | BASIC binary operators.
data BinOp =
    AddOp | SubOp | MulOp | DivOp | PowOp
    | EqOp | NEOp | LTOp | LEOp | GTOp | GEOp
    | AndOp | OrOp
    deriving (Enum,Show,Eq)

-- | BASIC expressions.
data Expr =
    LitX Literal
  | VarX Var
  | FnX VarName [Expr]
  | MinusX Expr
  | NotX Expr
  | BinX BinOp Expr Expr
  | BuiltinX Builtin [Expr]
  | NextZoneX                -- ^ commas in a @PRINT@ statement
  | EmptySeparatorX          -- ^ semicolons in a @PRINT@ statement
  | ParenX Expr
    deriving (Show,Eq)

isPrintSeparator :: Expr -> Bool
isPrintSeparator NextZoneX = True
isPrintSeparator EmptySeparatorX = True
isPrintSeparator _ = False

-- | BASIC statements.
data Statement =
    LetS Var Expr
  | DimS [(VarName, [Expr])]
  | GotoS Label
  | GosubS Label
  | OnGotoS Expr [Label]
  | OnGosubS Expr [Label]
  | ReturnS
  | IfS Expr [Tagged Statement] -- ^ includes all statements on the line following the @IF@
  | ForS VarName Expr Expr Expr
  | NextS (Maybe [VarName])
  | PrintS [Expr]
  | InputS (Maybe String) [Var]
  | EndS
  | StopS
  | RandomizeS
  | ReadS [Var]
  | RestoreS (Maybe Label)
  | DataS String
  | DefFnS VarName [VarName] Expr
  | RemS String
    deriving (Show,Eq)

-- | A line of BASIC, in fully parsed form, ready for interpretation.
data Line = Line Label [Tagged Statement]
    deriving (Show)