Haha
This commit is contained in:
1 parent
37ce925067
commit
6f80ac585c
22 files changed
+5350
-1
No files matched your search
+10
-1
@@ -1,6 +1,14 @@
|
||||
# ---> Agda
|
||||
*.agdai
|
||||
**.agdai
|
||||
MAlonzo/**
|
||||
**.hi
|
||||
**/*.hi
|
||||
**/*.o
|
||||
**/*.log
|
||||
**/*.aux
|
||||
**/*.dvi
|
||||
**/*.agdai
|
||||
Alisaie/Test
|
||||
|
||||
# ---> Nix
|
||||
# Ignore build outputs from performing a nix-build or `nix build` command
|
||||
@@ -10,3 +18,4 @@ result-*
|
||||
# Ignore automatically generated direnv output
|
||||
.direnv
|
||||
|
||||
Main
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
|
||||
Prog. Program ::= [Definition];
|
||||
|
||||
Def. Definition ::= Ident ":" Type "\n" Ident [Ident] "=" Exp;
|
||||
|
||||
KStar. Kind ::= "*";
|
||||
KArr. Kind1 ::= Kind "→" Kind;
|
||||
_. Kind1 ::= Kind;
|
||||
|
||||
token UIdent (upper (letter | digit | '_')*);
|
||||
|
||||
TString. Type1 ::= "String";
|
||||
TInt. Type1 ::= "Int";
|
||||
TDouble. Type1 ::= "Double";
|
||||
TChar. Type1 ::= "Char";
|
||||
TCustom. Type1 ::= UIdent;
|
||||
TArr. Type ::= Type1 "→" Type;
|
||||
TForall. Type ::= "∀" Ident ":" Kind "." Type;
|
||||
TLambda. Type ::= "λ" Ident ":" Kind "." Type;
|
||||
|
||||
coercions Type 1;
|
||||
|
||||
terminator Definition "";
|
||||
|
||||
terminator Ident "";
|
||||
|
||||
EVar. Exp4 ::= Ident;
|
||||
EInt. Exp4 ::= Integer;
|
||||
EDouble. Exp4 ::= Double;
|
||||
EChar. Exp4 ::= Char;
|
||||
EText. Exp4 ::= String;
|
||||
EApp. Exp2 ::= Exp2 Exp3; -- TODO: Fix shift reduce conflicts from these
|
||||
ETApp. Exp2 ::= Exp2 Type; -- TODO: Fix shift reduce conflicts from these
|
||||
EAdd. Exp1 ::= Exp1 "+" Exp2;
|
||||
ESub. Exp1 ::= Exp1 "-" Exp2;
|
||||
ELt. Exp1 ::= Exp1 "<" Exp2;
|
||||
EIf. Exp ::= "if" Exp "then" Exp "else" Exp;
|
||||
ETAbs. Exp ::= "Λ" Ident ":" Kind "." Exp;
|
||||
EAbs. Exp ::= "λ" Ident ":" Type "." Exp;
|
||||
|
||||
coercions Exp 4;
|
||||
|
||||
comment "--";
|
||||
comment "{-" "-}";
|
||||
@@ -0,0 +1,136 @@
|
||||
-- File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
-- Agda bindings for the Haskell abstract syntax data types.
|
||||
|
||||
module Alisaie.AST where
|
||||
|
||||
open import Agda.Builtin.Char using (Char)
|
||||
open import Agda.Builtin.Float public using () renaming (Float to Double)
|
||||
open import Agda.Builtin.Int public using () renaming (Int to Integer)
|
||||
open import Agda.Builtin.Int using () renaming (pos to #pos)
|
||||
open import Agda.Builtin.List using ([]; _∷_) renaming (List to #List)
|
||||
open import Agda.Builtin.String using () renaming
|
||||
( String to #String
|
||||
; primStringFromList to #stringFromList
|
||||
)
|
||||
|
||||
String = #List Char
|
||||
|
||||
{-# FOREIGN GHC import Prelude (Bool, Char, Double, Integer, String, (.)) #-}
|
||||
{-# FOREIGN GHC import qualified Data.Text #-}
|
||||
{-# FOREIGN GHC import qualified Alisaie.Abs #-}
|
||||
{-# FOREIGN GHC import Alisaie.Print (printTree) #-}
|
||||
|
||||
data Ident : Set where
|
||||
ident : #String → Ident
|
||||
|
||||
{-# COMPILE GHC Ident = data Alisaie.Abs.Ident (Alisaie.Abs.Ident) #-}
|
||||
|
||||
data UIdent : Set where
|
||||
uIdent : #String → UIdent
|
||||
|
||||
{-# COMPILE GHC UIdent = data Alisaie.Abs.UIdent (Alisaie.Abs.UIdent) #-}
|
||||
|
||||
mutual
|
||||
|
||||
data Program : Set where
|
||||
prog : (ds : #List Definition) → Program
|
||||
|
||||
{-# COMPILE GHC Program = data Alisaie.Abs.Program (Alisaie.Abs.Prog) #-}
|
||||
|
||||
data Definition : Set where
|
||||
def : (x₁ : Ident) (t : Type) (x₂ : Ident) (xs : #List Ident) (e : Exp) → Definition
|
||||
|
||||
{-# COMPILE GHC Definition = data Alisaie.Abs.Definition (Alisaie.Abs.Def) #-}
|
||||
|
||||
data Kind : Set where
|
||||
kStar : Kind
|
||||
kArr : (k₁ k₂ : Kind) → Kind
|
||||
|
||||
{-# COMPILE GHC Kind = data Alisaie.Abs.Kind
|
||||
( Alisaie.Abs.KStar
|
||||
| Alisaie.Abs.KArr
|
||||
) #-}
|
||||
|
||||
data Type : Set where
|
||||
tString : Type
|
||||
tInt : Type
|
||||
tDouble : Type
|
||||
tChar : Type
|
||||
tCustom : (x : UIdent) → Type
|
||||
tArr : (t₁ t₂ : Type) → Type
|
||||
tForall : (x : Ident) (k : Kind) (t : Type) → Type
|
||||
tLambda : (x : Ident) (k : Kind) (t : Type) → Type
|
||||
|
||||
{-# COMPILE GHC Type = data Alisaie.Abs.Type
|
||||
( Alisaie.Abs.TString
|
||||
| Alisaie.Abs.TInt
|
||||
| Alisaie.Abs.TDouble
|
||||
| Alisaie.Abs.TChar
|
||||
| Alisaie.Abs.TCustom
|
||||
| Alisaie.Abs.TArr
|
||||
| Alisaie.Abs.TForall
|
||||
| Alisaie.Abs.TLambda
|
||||
) #-}
|
||||
|
||||
data Exp : Set where
|
||||
eVar : (x : Ident) → Exp
|
||||
eInt : (x : Integer) → Exp
|
||||
eDouble : (x : Double) → Exp
|
||||
eChar : (x : Char) → Exp
|
||||
eText : (x : String) → Exp
|
||||
eApp : (e₁ e₂ : Exp) → Exp
|
||||
eTApp : (e : Exp) (t : Type) → Exp
|
||||
eAdd : (e₁ e₂ : Exp) → Exp
|
||||
eSub : (e₁ e₂ : Exp) → Exp
|
||||
eLt : (e₁ e₂ : Exp) → Exp
|
||||
eIf : (e₁ e₂ e₃ : Exp) → Exp
|
||||
eTAbs : (x : Ident) (k : Kind) (e : Exp) → Exp
|
||||
eAbs : (x : Ident) (t : Type) (e : Exp) → Exp
|
||||
|
||||
{-# COMPILE GHC Exp = data Alisaie.Abs.Exp
|
||||
( Alisaie.Abs.EVar
|
||||
| Alisaie.Abs.EInt
|
||||
| Alisaie.Abs.EDouble
|
||||
| Alisaie.Abs.EChar
|
||||
| Alisaie.Abs.EText
|
||||
| Alisaie.Abs.EApp
|
||||
| Alisaie.Abs.ETApp
|
||||
| Alisaie.Abs.EAdd
|
||||
| Alisaie.Abs.ESub
|
||||
| Alisaie.Abs.ELt
|
||||
| Alisaie.Abs.EIf
|
||||
| Alisaie.Abs.ETAbs
|
||||
| Alisaie.Abs.EAbs
|
||||
) #-}
|
||||
|
||||
-- Binding the pretty printers.
|
||||
|
||||
postulate
|
||||
printProgram : Program → #String
|
||||
printDefinition : Definition → #String
|
||||
printKind : Kind → #String
|
||||
printType : Type → #String
|
||||
printListDefinition : #List Definition → #String
|
||||
printListIdent : #List Ident → #String
|
||||
printExp : Exp → #String
|
||||
printIdent : Ident → #String
|
||||
printChar : Char → #String
|
||||
printDouble : Double → #String
|
||||
printInteger : Integer → #String
|
||||
printString : String → #String
|
||||
printUIdent : UIdent → #String
|
||||
|
||||
{-# COMPILE GHC printProgram = \ p -> Data.Text.pack (printTree (p :: Alisaie.Abs.Program)) #-}
|
||||
{-# COMPILE GHC printDefinition = \ d -> Data.Text.pack (printTree (d :: Alisaie.Abs.Definition)) #-}
|
||||
{-# COMPILE GHC printKind = \ k -> Data.Text.pack (printTree (k :: Alisaie.Abs.Kind)) #-}
|
||||
{-# COMPILE GHC printType = \ t -> Data.Text.pack (printTree (t :: Alisaie.Abs.Type)) #-}
|
||||
{-# COMPILE GHC printListDefinition = \ ds -> Data.Text.pack (printTree (ds :: [Alisaie.Abs.Definition])) #-}
|
||||
{-# COMPILE GHC printListIdent = \ xs -> Data.Text.pack (printTree (xs :: [Alisaie.Abs.Ident])) #-}
|
||||
{-# COMPILE GHC printExp = \ e -> Data.Text.pack (printTree (e :: Alisaie.Abs.Exp)) #-}
|
||||
{-# COMPILE GHC printIdent = \ x -> Data.Text.pack (printTree (x :: Alisaie.Abs.Ident)) #-}
|
||||
{-# COMPILE GHC printChar = \ x -> Data.Text.pack (printTree (x :: Char)) #-}
|
||||
{-# COMPILE GHC printDouble = \ x -> Data.Text.pack (printTree (x :: Double)) #-}
|
||||
{-# COMPILE GHC printInteger = \ x -> Data.Text.pack (printTree (x :: Integer)) #-}
|
||||
{-# COMPILE GHC printString = \ x -> Data.Text.pack (printTree (x :: String)) #-}
|
||||
{-# COMPILE GHC printUIdent = \ x -> Data.Text.pack (printTree (x :: Alisaie.Abs.UIdent)) #-}
|
||||
@@ -0,0 +1,56 @@
|
||||
-- File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
|
||||
-- | The abstract syntax of language Alisaie.
|
||||
|
||||
module Alisaie.Abs where
|
||||
|
||||
import Prelude (Char, Double, Integer, String)
|
||||
import qualified Prelude as C (Eq, Ord, Show, Read)
|
||||
import qualified Data.String
|
||||
|
||||
import qualified Data.Text
|
||||
|
||||
data Program = Prog [Definition]
|
||||
deriving (C.Eq, C.Ord, C.Show, C.Read)
|
||||
|
||||
data Definition = Def Ident Type Ident [Ident] Exp
|
||||
deriving (C.Eq, C.Ord, C.Show, C.Read)
|
||||
|
||||
data Kind = KStar | KArr Kind Kind
|
||||
deriving (C.Eq, C.Ord, C.Show, C.Read)
|
||||
|
||||
data Type
|
||||
= TString
|
||||
| TInt
|
||||
| TDouble
|
||||
| TChar
|
||||
| TCustom UIdent
|
||||
| TArr Type Type
|
||||
| TForall Ident Kind Type
|
||||
| TLambda Ident Kind Type
|
||||
deriving (C.Eq, C.Ord, C.Show, C.Read)
|
||||
|
||||
data Exp
|
||||
= EVar Ident
|
||||
| EInt Integer
|
||||
| EDouble Double
|
||||
| EChar Char
|
||||
| EText String
|
||||
| EApp Exp Exp
|
||||
| ETApp Exp Type
|
||||
| EAdd Exp Exp
|
||||
| ESub Exp Exp
|
||||
| ELt Exp Exp
|
||||
| EIf Exp Exp Exp
|
||||
| ETAbs Ident Kind Exp
|
||||
| EAbs Ident Type Exp
|
||||
deriving (C.Eq, C.Ord, C.Show, C.Read)
|
||||
|
||||
newtype Ident = Ident Data.Text.Text
|
||||
deriving (C.Eq, C.Ord, C.Show, C.Read, Data.String.IsString)
|
||||
|
||||
newtype UIdent = UIdent Data.Text.Text
|
||||
deriving (C.Eq, C.Ord, C.Show, C.Read, Data.String.IsString)
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
The Language Alisaie
|
||||
BNF Converter
|
||||
|
||||
|
||||
%Process by txt2tags to generate html or latex
|
||||
|
||||
|
||||
|
||||
This document was automatically generated by the //BNF-Converter//. It was generated together with the lexer, the parser, and the abstract syntax module, which guarantees that the document matches with the implementation of the language (provided no hand-hacking has taken place).
|
||||
|
||||
==The lexical structure of Alisaie==
|
||||
===Identifiers===
|
||||
Identifiers //Ident// are unquoted strings beginning with a letter,
|
||||
followed by any combination of letters, digits, and the characters ``_ '``
|
||||
reserved words excluded.
|
||||
|
||||
|
||||
===Literals===
|
||||
Character literals //Char// have the form
|
||||
``'``//c//``'``, where //c// is any single character.
|
||||
|
||||
|
||||
Double-precision float literals //Double// have the structure
|
||||
indicated by the regular expression ``digit+ '.' digit+ ('e' ('-')? digit+)?`` i.e.\
|
||||
two sequences of digits separated by a decimal point, optionally
|
||||
followed by an unsigned or negative exponent.
|
||||
|
||||
|
||||
Integer literals //Integer// are nonempty sequences of digits.
|
||||
|
||||
|
||||
String literals //String// have the form
|
||||
``"``//x//``"``}, where //x// is any sequence of any characters
|
||||
except ``"`` unless preceded by ``\``.
|
||||
|
||||
|
||||
|
||||
|
||||
UIdent literals are recognized by the regular expression
|
||||
`````upper ('_' | digit | letter)*`````
|
||||
|
||||
|
||||
===Reserved words and symbols===
|
||||
The set of reserved words is the set of terminals appearing in the grammar. Those reserved words that consist of non-letter characters are called symbols, and they are treated in a different way from those that are similar to identifiers. The lexer follows rules familiar from languages like Haskell, C, and Java, including longest match and spacing conventions.
|
||||
|
||||
The reserved words used in Alisaie are the following:
|
||||
| ``Char`` | ``Double`` | ``Int`` | ``String``
|
||||
| ``else`` | ``if`` | ``then`` | ``Λ``
|
||||
| ``λ`` | | |
|
||||
|
||||
The symbols used in Alisaie are the following:
|
||||
| : | = | * | →
|
||||
| ∀ | . | ( | )
|
||||
| + | - | < |
|
||||
|
||||
===Comments===
|
||||
Single-line comments begin with --.Multiple-line comments are enclosed with {- and -}.
|
||||
|
||||
==The syntactic structure of Alisaie==
|
||||
Non-terminals are enclosed between < and >.
|
||||
The symbols -> (production), **|** (union)
|
||||
and **eps** (empty rule) belong to the BNF notation.
|
||||
All other symbols are terminals.
|
||||
|
||||
| //Program// | -> | //[Definition]//
|
||||
| //Definition// | -> | //Ident// ``:`` //Type// //Ident// //[Ident]// ``=`` //Exp//
|
||||
| //Kind// | -> | ``*``
|
||||
| //Kind1// | -> | //Kind// ``→`` //Kind//
|
||||
| | **|** | //Kind//
|
||||
| //Type1// | -> | ``String``
|
||||
| | **|** | ``Int``
|
||||
| | **|** | ``Double``
|
||||
| | **|** | ``Char``
|
||||
| | **|** | //UIdent//
|
||||
| | **|** | ``(`` //Type// ``)``
|
||||
| //Type// | -> | //Type1// ``→`` //Type//
|
||||
| | **|** | ``∀`` //Ident// ``:`` //Kind// ``.`` //Type//
|
||||
| | **|** | ``λ`` //Ident// ``:`` //Kind// ``.`` //Type//
|
||||
| | **|** | //Type1//
|
||||
| //[Definition]// | -> | **eps**
|
||||
| | **|** | //Definition// //[Definition]//
|
||||
| //[Ident]// | -> | **eps**
|
||||
| | **|** | //Ident// //[Ident]//
|
||||
| //Exp4// | -> | //Ident//
|
||||
| | **|** | //Integer//
|
||||
| | **|** | //Double//
|
||||
| | **|** | //Char//
|
||||
| | **|** | //String//
|
||||
| | **|** | ``(`` //Exp// ``)``
|
||||
| //Exp2// | -> | //Exp2// //Exp3//
|
||||
| | **|** | //Exp2// //Type//
|
||||
| | **|** | //Exp3//
|
||||
| //Exp1// | -> | //Exp1// ``+`` //Exp2//
|
||||
| | **|** | //Exp1// ``-`` //Exp2//
|
||||
| | **|** | //Exp1// ``<`` //Exp2//
|
||||
| | **|** | //Exp2//
|
||||
| //Exp// | -> | ``if`` //Exp// ``then`` //Exp// ``else`` //Exp//
|
||||
| | **|** | ``Λ`` //Ident// ``:`` //Kind// ``.`` //Exp//
|
||||
| | **|** | ``λ`` //Ident// ``:`` //Type// ``.`` //Exp//
|
||||
| | **|** | //Exp1//
|
||||
| //Exp3// | -> | //Exp4//
|
||||
|
||||
|
||||
|
||||
%% File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
@@ -0,0 +1,44 @@
|
||||
-- File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
{-# LANGUAGE CPP #-}
|
||||
|
||||
-- | BNF Converter: Error Monad.
|
||||
--
|
||||
-- Module for backwards compatibility.
|
||||
--
|
||||
-- The generated parser now uses @'Either' String@ as error monad.
|
||||
-- This module defines a type synonym 'Err' and pattern synonyms
|
||||
-- 'Bad' and 'Ok' for 'Left' and 'Right'.
|
||||
|
||||
{-# LANGUAGE PatternSynonyms #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
|
||||
module Alisaie.ErrM where
|
||||
|
||||
import Prelude (id, const, Either(..), String)
|
||||
|
||||
import Control.Monad (MonadPlus(..))
|
||||
import Control.Applicative (Alternative(..))
|
||||
#if __GLASGOW_HASKELL__ >= 808
|
||||
import Control.Monad (MonadFail(..))
|
||||
#endif
|
||||
|
||||
-- | Error monad with 'String' error messages.
|
||||
type Err = Either String
|
||||
|
||||
pattern Bad msg = Left msg
|
||||
pattern Ok a = Right a
|
||||
|
||||
#if __GLASGOW_HASKELL__ >= 808
|
||||
instance MonadFail Err where
|
||||
fail = Bad
|
||||
#endif
|
||||
|
||||
instance Alternative Err where
|
||||
empty = Left "Err.empty"
|
||||
(<|>) Left{} = id
|
||||
(<|>) x@Right{} = const x
|
||||
|
||||
instance MonadPlus Err where
|
||||
mzero = empty
|
||||
mplus = (<|>)
|
||||
@@ -0,0 +1,56 @@
|
||||
-- File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
-- Basic I/O library.
|
||||
|
||||
module Alisaie.IOLib where
|
||||
|
||||
open import Agda.Builtin.IO public using (IO)
|
||||
open import Agda.Builtin.List public using (List; []; _∷_)
|
||||
open import Agda.Builtin.String public using (String)
|
||||
renaming (primStringFromList to stringFromList)
|
||||
open import Agda.Builtin.Unit public using (⊤)
|
||||
|
||||
-- I/O monad.
|
||||
|
||||
postulate
|
||||
return : ∀ {a} {A : Set a} → A → IO A
|
||||
_>>=_ : ∀ {a b} {A : Set a} {B : Set b} → IO A → (A → IO B) → IO B
|
||||
|
||||
{-# COMPILE GHC return = \ _ _ -> return #-}
|
||||
{-# COMPILE GHC _>>=_ = \ _ _ _ _ -> (>>=) #-}
|
||||
|
||||
infixl 1 _>>=_ _>>_
|
||||
|
||||
_>>_ : ∀ {b} {B : Set b} → IO ⊤ → IO B → IO B
|
||||
_>>_ = λ m m' → m >>= λ _ → m'
|
||||
|
||||
-- Co-bind and functoriality.
|
||||
|
||||
infixr 1 _=<<_ _<$>_
|
||||
|
||||
_=<<_ : ∀ {a b} {A : Set a} {B : Set b} → (A → IO B) → IO A → IO B
|
||||
k =<< m = m >>= k
|
||||
|
||||
_<$>_ : ∀ {a b} {A : Set a} {B : Set b} → (A → B) → IO A → IO B
|
||||
f <$> m = do
|
||||
a ← m
|
||||
return (f a)
|
||||
|
||||
-- Binding basic I/O functionality.
|
||||
|
||||
{-# FOREIGN GHC import qualified Data.Text #-}
|
||||
{-# FOREIGN GHC import qualified Data.Text.IO #-}
|
||||
{-# FOREIGN GHC import qualified System.Exit #-}
|
||||
{-# FOREIGN GHC import qualified System.Environment #-}
|
||||
{-# FOREIGN GHC import qualified System.IO #-}
|
||||
|
||||
postulate
|
||||
exitFailure : ∀{a} {A : Set a} → IO A
|
||||
getArgs : IO (List String)
|
||||
putStrLn : String → IO ⊤
|
||||
readFiniteFile : String → IO String
|
||||
|
||||
{-# COMPILE GHC exitFailure = \ _ _ -> System.Exit.exitFailure #-}
|
||||
{-# COMPILE GHC getArgs = fmap (map Data.Text.pack) System.Environment.getArgs #-}
|
||||
{-# COMPILE GHC putStrLn = System.IO.putStrLn . Data.Text.unpack #-}
|
||||
{-# COMPILE GHC readFiniteFile = Data.Text.IO.readFile . Data.Text.unpack #-}
|
||||
+564
@@ -0,0 +1,564 @@
|
||||
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
|
||||
{-# OPTIONS_GHC -fno-warn-tabs #-}
|
||||
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
|
||||
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE MagicHash #-}
|
||||
{-# LINE 4 "Alisaie/Lex.x" #-}
|
||||
{-# OPTIONS -Wno-incomplete-patterns #-}
|
||||
{-# OPTIONS_GHC -w #-}
|
||||
|
||||
{-# LANGUAGE PatternSynonyms #-}
|
||||
|
||||
module Alisaie.Lex where
|
||||
|
||||
import Prelude
|
||||
|
||||
import qualified Data.Text
|
||||
import qualified Data.Bits
|
||||
import Data.Char (ord)
|
||||
import Data.Function (on)
|
||||
import Data.Word (Word8)
|
||||
#include "ghcconfig.h"
|
||||
import qualified Data.Array
|
||||
import qualified Data.Char
|
||||
import Data.Array.Base (unsafeAt)
|
||||
import GHC.Exts (Addr#,Int#,Int(I#),(*#),(+#),(-#),(==#),(>=#),indexCharOffAddr#,indexInt16OffAddr#,indexInt32OffAddr#,int2Word#,narrow16Int#,narrow32Int#,negateInt#,or#,ord#,uncheckedShiftL#,word2Int#)
|
||||
import qualified GHC.Exts
|
||||
alex_tab_size :: Int
|
||||
alex_tab_size = 8
|
||||
alex_base :: AlexAddr
|
||||
alex_base = AlexA#
|
||||
"\xf8\xff\xff\xff\xdb\x00\x00\x00\xb4\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x74\xff\xff\xff\xdc\x00\x00\x00\x1c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x01\x00\x00\x9d\x01\x00\x00\x1d\x02\x00\x00\xe0\xff\xff\xff\xd8\xff\xff\xff\xe5\xff\xff\xff\x8c\x00\x00\x00\x9a\x00\x00\x00\xe6\xff\xff\xff\xf6\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdc\x02\x00\x00\x1d\x03\x00\x00\x5d\x03\x00\x00\x53\x04\x00\x00\x00\x00\x00\x00\xc4\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x05\x00\x00\xd7\x05\x00\x00\x48\x06\x00\x00\x45\x05\x00\x00\x00\x00\x00\x00\x89\x06\x00\x00\xfa\x06\x00\x00\x3b\x07\x00\x00\x0e\x08\x00\x00\xe7\x08\x00\x00\xee\x02\x00\x00\xf8\x02\x00\x00\x04\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x09\x00\x00\x23\x0a\x00\x00\x00\x00\x00\x00\x35\x03\x00\x00\x00\x00\x00\x00\x74\x0a\x00\x00\x3c\x04\x00\x00\x74\x0b\x00\x00\xf4\x0b\x00\x00\x74\x0c\x00\x00\x75\x0c\x00\x00\xf5\x0c\x00\x00\x75\x0d\x00\x00\xf5\x0d\x00\x00\x75\x0e\x00\x00\xf5\x0e\x00\x00\x8e\xff\xff\xff\xbc\x07\x00\x00\x95\xff\xff\xff\x7c\xff\xff\xff"#
|
||||
|
||||
alex_table :: AlexAddr
|
||||
alex_table = AlexA#
|
||||
"\x00\x00\x32\x00\x32\x00\x32\x00\x32\x00\x32\x00\x31\x00\x2d\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x34\x00\x21\x00\x06\x00\x31\x00\x41\x00\x31\x00\x32\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x00\x31\x00\x31\x00\x31\x00\x31\x00\x00\x00\x10\x00\x31\x00\x00\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x31\x00\x00\x00\x31\x00\x31\x00\x00\x00\x31\x00\x00\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x42\x00\x11\x00\x00\x00\x00\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x00\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x00\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x00\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x2f\x00\x02\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04\x00\x04Line truncated
|
||||
|
||||
alex_check :: AlexAddr
|
||||
alex_check = AlexA#
|
||||
"\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x92\x00\x27\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x2d\x00\x2d\x00\x86\x00\x80\x00\x88\x00\x9b\x00\x20\x00\xff\xff\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\xff\xff\x3c\x00\x3d\x00\xff\xff\xbb\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc3\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xce\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe2\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\xff\xff\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xff\xff\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\xff\xff\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xff\xff\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3Line truncated
|
||||
|
||||
alex_deflt :: AlexAddr
|
||||
alex_deflt = AlexA#
|
||||
"\xff\xff\x34\x00\x34\x00\x04\x00\x05\x00\x34\x00\xff\xff\xff\xff\xff\xff\x0a\x00\x24\x00\x05\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x16\x00\x17\x00\x1b\x00\x16\x00\x17\x00\x1b\x00\x1b\x00\x1e\x00\x0a\x00\x1f\x00\x21\x00\x0e\x00\x21\x00\x1e\x00\x21\x00\x0e\x00\x1f\x00\x04\x00\x24\x00\x21\x00\x0e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x34\x00\xff\xff\x21\x00\x1b\x00\x0e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
|
||||
|
||||
alex_accept = Data.Array.listArray (0 :: Int, 66)
|
||||
[ AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAcc 8
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAcc 7
|
||||
, AlexAcc 6
|
||||
, AlexAcc 5
|
||||
, AlexAcc 4
|
||||
, AlexAcc 3
|
||||
, AlexAcc 2
|
||||
, AlexAcc 1
|
||||
, AlexAcc 0
|
||||
, AlexAccSkip
|
||||
, AlexAccSkip
|
||||
, AlexAccSkip
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
, AlexAccNone
|
||||
]
|
||||
|
||||
alex_actions = Data.Array.array (0 :: Int, 9)
|
||||
[ (8,alex_action_3)
|
||||
, (7,alex_action_9)
|
||||
, (6,alex_action_9)
|
||||
, (5,alex_action_8)
|
||||
, (4,alex_action_7)
|
||||
, (3,alex_action_6)
|
||||
, (2,alex_action_5)
|
||||
, (1,alex_action_4)
|
||||
, (0,alex_action_3)
|
||||
]
|
||||
|
||||
alex_action_3 = tok (eitherResIdent TV)
|
||||
alex_action_4 = tok (eitherResIdent T_UIdent)
|
||||
alex_action_5 = tok (eitherResIdent TV)
|
||||
alex_action_6 = tok (TL . unescapeInitTail)
|
||||
alex_action_7 = tok TC
|
||||
alex_action_8 = tok TI
|
||||
alex_action_9 = tok TD
|
||||
|
||||
#define ALEX_GHC 1
|
||||
#define ALEX_NOPRED 1
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- ALEX TEMPLATE
|
||||
--
|
||||
-- This code is in the PUBLIC DOMAIN; you may copy it freely and use
|
||||
-- it for any purpose whatsoever.
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- INTERNALS and main scanner engine
|
||||
|
||||
#ifdef ALEX_GHC
|
||||
# define ILIT(n) n#
|
||||
# define IBOX(n) (I# (n))
|
||||
# define FAST_INT Int#
|
||||
-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
|
||||
# if __GLASGOW_HASKELL__ > 706
|
||||
# define CMP_GEQ(n,m) (((n) >=# (m)) :: Int#)
|
||||
# define CMP_EQ(n,m) (((n) ==# (m)) :: Int#)
|
||||
# define CMP_MKBOOL(x) ((GHC.Exts.tagToEnum# (x)) :: Bool)
|
||||
# else
|
||||
# define CMP_GEQ(n,m) (((n) >= (m)) :: Bool)
|
||||
# define CMP_EQ(n,m) (((n) == (m)) :: Bool)
|
||||
# define CMP_MKBOOL(x) ((x) :: Bool)
|
||||
# endif
|
||||
# define GTE(n,m) CMP_MKBOOL(CMP_GEQ(n,m))
|
||||
# define EQ(n,m) CMP_MKBOOL(CMP_EQ(n,m))
|
||||
# define PLUS(n,m) (n +# m)
|
||||
# define MINUS(n,m) (n -# m)
|
||||
# define TIMES(n,m) (n *# m)
|
||||
# define NEGATE(n) (negateInt# (n))
|
||||
# define IF_GHC(x) (x)
|
||||
#else
|
||||
# define ILIT(n) (n)
|
||||
# define IBOX(n) (n)
|
||||
# define FAST_INT Int
|
||||
# define GTE(n,m) (n >= m)
|
||||
# define EQ(n,m) (n == m)
|
||||
# define PLUS(n,m) (n + m)
|
||||
# define MINUS(n,m) (n - m)
|
||||
# define TIMES(n,m) (n * m)
|
||||
# define NEGATE(n) (negate (n))
|
||||
# define IF_GHC(x)
|
||||
#endif
|
||||
|
||||
#ifdef ALEX_GHC
|
||||
data AlexAddr = AlexA# Addr#
|
||||
-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
|
||||
|
||||
{-# INLINE alexIndexInt16OffAddr #-}
|
||||
alexIndexInt16OffAddr :: AlexAddr -> Int# -> Int#
|
||||
alexIndexInt16OffAddr (AlexA# arr) off =
|
||||
#if __GLASGOW_HASKELL__ >= 901
|
||||
GHC.Exts.int16ToInt# -- qualified import because it doesn't exist on older GHC's
|
||||
#endif
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
(GHC.Exts.word16ToInt16# (GHC.Exts.wordToWord16# (GHC.Exts.byteSwap16# (GHC.Exts.word16ToWord# (GHC.Exts.int16ToWord16#
|
||||
#endif
|
||||
(indexInt16OffAddr# arr off)
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
)))))
|
||||
#endif
|
||||
#else
|
||||
alexIndexInt16OffAddr = (Data.Array.!)
|
||||
#endif
|
||||
|
||||
#ifdef ALEX_GHC
|
||||
{-# INLINE alexIndexInt32OffAddr #-}
|
||||
alexIndexInt32OffAddr :: AlexAddr -> Int# -> Int#
|
||||
alexIndexInt32OffAddr (AlexA# arr) off =
|
||||
#if __GLASGOW_HASKELL__ >= 901
|
||||
GHC.Exts.int32ToInt# -- qualified import because it doesn't exist on older GHC's
|
||||
#endif
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
(GHC.Exts.word32ToInt32# (GHC.Exts.wordToWord32# (GHC.Exts.byteSwap32# (GHC.Exts.word32ToWord# (GHC.Exts.int32ToWord32#
|
||||
#endif
|
||||
(indexInt32OffAddr# arr off)
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
)))))
|
||||
#endif
|
||||
#else
|
||||
alexIndexInt32OffAddr = (Data.Array.!)
|
||||
#endif
|
||||
|
||||
#ifdef ALEX_GHC
|
||||
-- GHC >= 503, unsafeAt is available from Data.Array.Base.
|
||||
quickIndex = unsafeAt
|
||||
#else
|
||||
quickIndex = (Data.Array.!)
|
||||
#endif
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- Main lexing routines
|
||||
|
||||
data AlexReturn a
|
||||
= AlexEOF
|
||||
| AlexError !AlexInput
|
||||
| AlexSkip !AlexInput !Int
|
||||
| AlexToken !AlexInput !Int a
|
||||
|
||||
-- alexScan :: AlexInput -> StartCode -> AlexReturn a
|
||||
alexScan input__ IBOX(sc)
|
||||
= alexScanUser (error "alex rule requiring context was invoked by alexScan; use alexScanUser instead?") input__ IBOX(sc)
|
||||
|
||||
-- If the generated alexScan/alexScanUser functions are called multiple times
|
||||
-- in the same file, alexScanUser gets broken out into a separate function and
|
||||
-- increases memory usage. Make sure GHC inlines this function and optimizes it.
|
||||
{-# INLINE alexScanUser #-}
|
||||
|
||||
alexScanUser user__ input__ IBOX(sc)
|
||||
= case alex_scan_tkn user__ input__ ILIT(0) input__ sc AlexNone of
|
||||
(AlexNone, input__') ->
|
||||
case alexGetByte input__ of
|
||||
Nothing ->
|
||||
#ifdef ALEX_DEBUG
|
||||
Debug.Trace.trace ("End of input.") $
|
||||
#endif
|
||||
AlexEOF
|
||||
Just _ ->
|
||||
#ifdef ALEX_DEBUG
|
||||
Debug.Trace.trace ("Error.") $
|
||||
#endif
|
||||
AlexError input__'
|
||||
|
||||
(AlexLastSkip input__'' len, _) ->
|
||||
#ifdef ALEX_DEBUG
|
||||
Debug.Trace.trace ("Skipping.") $
|
||||
#endif
|
||||
AlexSkip input__'' len
|
||||
|
||||
(AlexLastAcc k input__''' len, _) ->
|
||||
#ifdef ALEX_DEBUG
|
||||
Debug.Trace.trace ("Accept.") $
|
||||
#endif
|
||||
AlexToken input__''' len ((Data.Array.!) alex_actions k)
|
||||
|
||||
|
||||
-- Push the input through the DFA, remembering the most recent accepting
|
||||
-- state it encountered.
|
||||
|
||||
alex_scan_tkn user__ orig_input len input__ s last_acc =
|
||||
input__ `seq` -- strict in the input
|
||||
let
|
||||
new_acc = (check_accs (alex_accept `quickIndex` IBOX(s)))
|
||||
in
|
||||
new_acc `seq`
|
||||
case alexGetByte input__ of
|
||||
Nothing -> (new_acc, input__)
|
||||
Just (c, new_input) ->
|
||||
#ifdef ALEX_DEBUG
|
||||
Debug.Trace.trace ("State: " ++ show IBOX(s) ++ ", char: " ++ show c ++ " " ++ (show . Data.Char.chr . fromIntegral) c) $
|
||||
#endif
|
||||
case fromIntegral c of { IBOX(ord_c) ->
|
||||
let
|
||||
base = alexIndexInt32OffAddr alex_base s
|
||||
offset = PLUS(base,ord_c)
|
||||
|
||||
new_s = if GTE(offset,ILIT(0))
|
||||
&& let check = alexIndexInt16OffAddr alex_check offset
|
||||
in EQ(check,ord_c)
|
||||
then alexIndexInt16OffAddr alex_table offset
|
||||
else alexIndexInt16OffAddr alex_deflt s
|
||||
in
|
||||
case new_s of
|
||||
ILIT(-1) -> (new_acc, input__)
|
||||
-- on an error, we want to keep the input *before* the
|
||||
-- character that failed, not after.
|
||||
_ -> alex_scan_tkn user__ orig_input
|
||||
#ifdef ALEX_LATIN1
|
||||
PLUS(len,ILIT(1))
|
||||
-- issue 119: in the latin1 encoding, *each* byte is one character
|
||||
#else
|
||||
(if c < 0x80 || c >= 0xC0 then PLUS(len,ILIT(1)) else len)
|
||||
-- note that the length is increased ONLY if this is the 1st byte in a char encoding)
|
||||
#endif
|
||||
new_input new_s new_acc
|
||||
}
|
||||
where
|
||||
check_accs (AlexAccNone) = last_acc
|
||||
check_accs (AlexAcc a ) = AlexLastAcc a input__ IBOX(len)
|
||||
check_accs (AlexAccSkip) = AlexLastSkip input__ IBOX(len)
|
||||
#ifndef ALEX_NOPRED
|
||||
check_accs (AlexAccPred a predx rest)
|
||||
| predx user__ orig_input IBOX(len) input__
|
||||
= AlexLastAcc a input__ IBOX(len)
|
||||
| otherwise
|
||||
= check_accs rest
|
||||
check_accs (AlexAccSkipPred predx rest)
|
||||
| predx user__ orig_input IBOX(len) input__
|
||||
= AlexLastSkip input__ IBOX(len)
|
||||
| otherwise
|
||||
= check_accs rest
|
||||
#endif
|
||||
|
||||
data AlexLastAcc
|
||||
= AlexNone
|
||||
| AlexLastAcc !Int !AlexInput !Int
|
||||
| AlexLastSkip !AlexInput !Int
|
||||
|
||||
data AlexAcc user
|
||||
= AlexAccNone
|
||||
| AlexAcc Int
|
||||
| AlexAccSkip
|
||||
#ifndef ALEX_NOPRED
|
||||
| AlexAccPred Int (AlexAccPred user) (AlexAcc user)
|
||||
| AlexAccSkipPred (AlexAccPred user) (AlexAcc user)
|
||||
|
||||
type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- Predicates on a rule
|
||||
|
||||
alexAndPred p1 p2 user__ in1 len in2
|
||||
= p1 user__ in1 len in2 && p2 user__ in1 len in2
|
||||
|
||||
--alexPrevCharIsPred :: Char -> AlexAccPred _
|
||||
alexPrevCharIs c _ input__ _ _ = c == alexInputPrevChar input__
|
||||
|
||||
alexPrevCharMatches f _ input__ _ _ = f (alexInputPrevChar input__)
|
||||
|
||||
--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _
|
||||
alexPrevCharIsOneOf arr _ input__ _ _ = arr Data.Array.! alexInputPrevChar input__
|
||||
|
||||
--alexRightContext :: Int -> AlexAccPred _
|
||||
alexRightContext IBOX(sc) user__ _ _ input__ =
|
||||
case alex_scan_tkn user__ input__ ILIT(0) input__ sc AlexNone of
|
||||
(AlexNone, _) -> False
|
||||
_ -> True
|
||||
-- TODO: there's no need to find the longest
|
||||
-- match when checking the right context, just
|
||||
-- the first match will do.
|
||||
#endif
|
||||
{-# LINE 73 "Alisaie/Lex.x" #-}
|
||||
-- | Create a token with position.
|
||||
tok :: (Data.Text.Text -> Tok) -> (Posn -> Data.Text.Text -> Token)
|
||||
tok f p = PT p . f
|
||||
|
||||
-- | Token without position.
|
||||
data Tok
|
||||
= TK {-# UNPACK #-} !TokSymbol -- ^ Reserved word or symbol.
|
||||
| TL !Data.Text.Text -- ^ String literal.
|
||||
| TI !Data.Text.Text -- ^ Integer literal.
|
||||
| TV !Data.Text.Text -- ^ Identifier.
|
||||
| TD !Data.Text.Text -- ^ Float literal.
|
||||
| TC !Data.Text.Text -- ^ Character literal.
|
||||
| T_UIdent !Data.Text.Text
|
||||
deriving (Eq, Show, Ord)
|
||||
|
||||
-- | Smart constructor for 'Tok' for the sake of backwards compatibility.
|
||||
pattern TS :: Data.Text.Text -> Int -> Tok
|
||||
pattern TS t i = TK (TokSymbol t i)
|
||||
|
||||
-- | Keyword or symbol tokens have a unique ID.
|
||||
data TokSymbol = TokSymbol
|
||||
{ tsText :: Data.Text.Text
|
||||
-- ^ Keyword or symbol text.
|
||||
, tsID :: !Int
|
||||
-- ^ Unique ID.
|
||||
} deriving (Show)
|
||||
|
||||
-- | Keyword/symbol equality is determined by the unique ID.
|
||||
instance Eq TokSymbol where (==) = (==) `on` tsID
|
||||
|
||||
-- | Keyword/symbol ordering is determined by the unique ID.
|
||||
instance Ord TokSymbol where compare = compare `on` tsID
|
||||
|
||||
-- | Token with position.
|
||||
data Token
|
||||
= PT Posn Tok
|
||||
| Err Posn
|
||||
deriving (Eq, Show, Ord)
|
||||
|
||||
-- | Pretty print a position.
|
||||
printPosn :: Posn -> String
|
||||
printPosn (Pn _ l c) = "line " ++ show l ++ ", column " ++ show c
|
||||
|
||||
-- | Pretty print the position of the first token in the list.
|
||||
tokenPos :: [Token] -> String
|
||||
tokenPos (t:_) = printPosn (tokenPosn t)
|
||||
tokenPos [] = "end of file"
|
||||
|
||||
-- | Get the position of a token.
|
||||
tokenPosn :: Token -> Posn
|
||||
tokenPosn (PT p _) = p
|
||||
tokenPosn (Err p) = p
|
||||
|
||||
-- | Get line and column of a token.
|
||||
tokenLineCol :: Token -> (Int, Int)
|
||||
tokenLineCol = posLineCol . tokenPosn
|
||||
|
||||
-- | Get line and column of a position.
|
||||
posLineCol :: Posn -> (Int, Int)
|
||||
posLineCol (Pn _ l c) = (l,c)
|
||||
|
||||
-- | Convert a token into "position token" form.
|
||||
mkPosToken :: Token -> ((Int, Int), Data.Text.Text)
|
||||
mkPosToken t = (tokenLineCol t, tokenText t)
|
||||
|
||||
-- | Convert a token to its text.
|
||||
tokenText :: Token -> Data.Text.Text
|
||||
tokenText t = case t of
|
||||
PT _ (TS s _) -> s
|
||||
PT _ (TL s) -> Data.Text.pack (show s)
|
||||
PT _ (TI s) -> s
|
||||
PT _ (TV s) -> s
|
||||
PT _ (TD s) -> s
|
||||
PT _ (TC s) -> s
|
||||
Err _ -> Data.Text.pack "#error"
|
||||
PT _ (T_UIdent s) -> s
|
||||
|
||||
-- | Convert a token to a string.
|
||||
prToken :: Token -> String
|
||||
prToken t = Data.Text.unpack (tokenText t)
|
||||
|
||||
-- | Finite map from text to token organized as binary search tree.
|
||||
data BTree
|
||||
= N -- ^ Nil (leaf).
|
||||
| B Data.Text.Text Tok BTree BTree
|
||||
-- ^ Binary node.
|
||||
deriving (Show)
|
||||
|
||||
-- | Convert potential keyword into token or use fallback conversion.
|
||||
eitherResIdent :: (Data.Text.Text -> Tok) -> Data.Text.Text -> Tok
|
||||
eitherResIdent tv s = treeFind resWords
|
||||
where
|
||||
treeFind N = tv s
|
||||
treeFind (B a t left right) =
|
||||
case compare s a of
|
||||
LT -> treeFind left
|
||||
GT -> treeFind right
|
||||
EQ -> t
|
||||
|
||||
-- | The keywords and symbols of the language organized as binary search tree.
|
||||
resWords :: BTree
|
||||
resWords =
|
||||
b "Double" 11
|
||||
(b "." 6
|
||||
(b "*" 3 (b ")" 2 (b "(" 1 N N) N) (b "-" 5 (b "+" 4 N N) N))
|
||||
(b "=" 9 (b "<" 8 (b ":" 7 N N) N) (b "Char" 10 N N)))
|
||||
(b "then" 16
|
||||
(b "else" 14 (b "String" 13 (b "Int" 12 N N) N) (b "if" 15 N N))
|
||||
(b "\8594" 19
|
||||
(b "\955" 18 (b "\923" 17 N N) N) (b "\8704" 20 N N)))
|
||||
where
|
||||
b s n = B bs (TS bs n)
|
||||
where
|
||||
bs = Data.Text.pack s
|
||||
|
||||
-- | Unquote string literal.
|
||||
unescapeInitTail :: Data.Text.Text -> Data.Text.Text
|
||||
unescapeInitTail = Data.Text.pack . unesc . tail . Data.Text.unpack
|
||||
where
|
||||
unesc s = case s of
|
||||
'\\':c:cs | elem c ['\"', '\\', '\''] -> c : unesc cs
|
||||
'\\':'n':cs -> '\n' : unesc cs
|
||||
'\\':'t':cs -> '\t' : unesc cs
|
||||
'\\':'r':cs -> '\r' : unesc cs
|
||||
'\\':'f':cs -> '\f' : unesc cs
|
||||
'"':[] -> []
|
||||
c:cs -> c : unesc cs
|
||||
_ -> []
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Alex wrapper code.
|
||||
-- A modified "posn" wrapper.
|
||||
-------------------------------------------------------------------
|
||||
|
||||
data Posn = Pn !Int !Int !Int
|
||||
deriving (Eq, Show, Ord)
|
||||
|
||||
alexStartPos :: Posn
|
||||
alexStartPos = Pn 0 1 1
|
||||
|
||||
alexMove :: Posn -> Char -> Posn
|
||||
alexMove (Pn a l c) '\t' = Pn (a+1) l (((c+7) `div` 8)*8+1)
|
||||
alexMove (Pn a l c) '\n' = Pn (a+1) (l+1) 1
|
||||
alexMove (Pn a l c) _ = Pn (a+1) l (c+1)
|
||||
|
||||
type Byte = Word8
|
||||
|
||||
type AlexInput = (Posn, -- current position,
|
||||
Char, -- previous char
|
||||
[Byte], -- pending bytes on the current char
|
||||
Data.Text.Text) -- current input string
|
||||
|
||||
tokens :: Data.Text.Text -> [Token]
|
||||
tokens str = go (alexStartPos, '\n', [], str)
|
||||
where
|
||||
go :: AlexInput -> [Token]
|
||||
go inp@(pos, _, _, str) =
|
||||
case alexScan inp 0 of
|
||||
AlexEOF -> []
|
||||
AlexError (pos, _, _, _) -> [Err pos]
|
||||
AlexSkip inp' len -> go inp'
|
||||
AlexToken inp' len act -> act pos (Data.Text.take len str) : (go inp')
|
||||
|
||||
alexGetByte :: AlexInput -> Maybe (Byte,AlexInput)
|
||||
alexGetByte (p, c, (b:bs), s) = Just (b, (p, c, bs, s))
|
||||
alexGetByte (p, _, [], s) =
|
||||
case Data.Text.uncons s of
|
||||
Nothing -> Nothing
|
||||
Just (c,s) ->
|
||||
let p' = alexMove p c
|
||||
(b:bs) = utf8Encode c
|
||||
in p' `seq` Just (b, (p', c, bs, s))
|
||||
|
||||
alexInputPrevChar :: AlexInput -> Char
|
||||
alexInputPrevChar (p, c, bs, s) = c
|
||||
|
||||
-- | Encode a Haskell String to a list of Word8 values, in UTF8 format.
|
||||
utf8Encode :: Char -> [Word8]
|
||||
utf8Encode = map fromIntegral . go . ord
|
||||
where
|
||||
go oc
|
||||
| oc <= 0x7f = [oc]
|
||||
|
||||
| oc <= 0x7ff = [ 0xc0 + (oc `Data.Bits.shiftR` 6)
|
||||
, 0x80 + oc Data.Bits..&. 0x3f
|
||||
]
|
||||
|
||||
| oc <= 0xffff = [ 0xe0 + (oc `Data.Bits.shiftR` 12)
|
||||
, 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f)
|
||||
, 0x80 + oc Data.Bits..&. 0x3f
|
||||
]
|
||||
| otherwise = [ 0xf0 + (oc `Data.Bits.shiftR` 18)
|
||||
, 0x80 + ((oc `Data.Bits.shiftR` 12) Data.Bits..&. 0x3f)
|
||||
, 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f)
|
||||
, 0x80 + oc Data.Bits..&. 0x3f
|
||||
]
|
||||
+270
@@ -0,0 +1,270 @@
|
||||
-- -*- haskell -*- File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
-- Lexer definition for use with Alex 3
|
||||
{
|
||||
{-# OPTIONS -Wno-incomplete-patterns #-}
|
||||
{-# OPTIONS_GHC -w #-}
|
||||
|
||||
{-# LANGUAGE PatternSynonyms #-}
|
||||
|
||||
module Alisaie.Lex where
|
||||
|
||||
import Prelude
|
||||
|
||||
import qualified Data.Text
|
||||
import qualified Data.Bits
|
||||
import Data.Char (ord)
|
||||
import Data.Function (on)
|
||||
import Data.Word (Word8)
|
||||
}
|
||||
|
||||
-- Predefined character classes
|
||||
|
||||
$c = [A-Z\192-\222] # [\215] -- capital isolatin1 letter (215 = \times)
|
||||
$s = [a-z\223-\255] # [\247] -- small isolatin1 letter (247 = \div )
|
||||
$l = [$c $s] -- letter
|
||||
$d = [0-9] -- digit
|
||||
$i = [$l $d _ '] -- identifier character
|
||||
$u = [. \n] -- universal: any character
|
||||
|
||||
-- Symbols and non-identifier-like reserved words
|
||||
|
||||
@rsyms = \λ | \Λ | \: | \= | \* | \→ | \∀ | \. | \( | \) | \+ | \- | \<
|
||||
|
||||
:-
|
||||
|
||||
-- Line comment "--"
|
||||
"--" [.]* ;
|
||||
|
||||
-- Block comment "{-" "-}"
|
||||
\{ \- [$u # \-]* \- ([$u # [\- \}]] [$u # \-]* \- | \-)* \} ;
|
||||
|
||||
-- Whitespace (skipped)
|
||||
$white+ ;
|
||||
|
||||
-- Symbols
|
||||
@rsyms
|
||||
{ tok (eitherResIdent TV) }
|
||||
|
||||
-- token UIdent
|
||||
$c (\_ | ($d | $l)) *
|
||||
{ tok (eitherResIdent T_UIdent) }
|
||||
|
||||
-- Keywords and Ident
|
||||
$l $i*
|
||||
{ tok (eitherResIdent TV) }
|
||||
|
||||
-- String
|
||||
\" ([$u # [\" \\ \n]] | (\\ (\" | \\ | \' | n | t | r | f)))* \"
|
||||
{ tok (TL . unescapeInitTail) }
|
||||
|
||||
-- Char
|
||||
\' ($u # [\' \\] | \\ [\\ \' n t r f]) \'
|
||||
{ tok TC }
|
||||
|
||||
-- Integer
|
||||
$d+
|
||||
{ tok TI }
|
||||
|
||||
-- Double
|
||||
$d+ \. $d+ (e (\-)? $d+)?
|
||||
{ tok TD }
|
||||
|
||||
{
|
||||
-- | Create a token with position.
|
||||
tok :: (Data.Text.Text -> Tok) -> (Posn -> Data.Text.Text -> Token)
|
||||
tok f p = PT p . f
|
||||
|
||||
-- | Token without position.
|
||||
data Tok
|
||||
= TK {-# UNPACK #-} !TokSymbol -- ^ Reserved word or symbol.
|
||||
| TL !Data.Text.Text -- ^ String literal.
|
||||
| TI !Data.Text.Text -- ^ Integer literal.
|
||||
| TV !Data.Text.Text -- ^ Identifier.
|
||||
| TD !Data.Text.Text -- ^ Float literal.
|
||||
| TC !Data.Text.Text -- ^ Character literal.
|
||||
| T_UIdent !Data.Text.Text
|
||||
deriving (Eq, Show, Ord)
|
||||
|
||||
-- | Smart constructor for 'Tok' for the sake of backwards compatibility.
|
||||
pattern TS :: Data.Text.Text -> Int -> Tok
|
||||
pattern TS t i = TK (TokSymbol t i)
|
||||
|
||||
-- | Keyword or symbol tokens have a unique ID.
|
||||
data TokSymbol = TokSymbol
|
||||
{ tsText :: Data.Text.Text
|
||||
-- ^ Keyword or symbol text.
|
||||
, tsID :: !Int
|
||||
-- ^ Unique ID.
|
||||
} deriving (Show)
|
||||
|
||||
-- | Keyword/symbol equality is determined by the unique ID.
|
||||
instance Eq TokSymbol where (==) = (==) `on` tsID
|
||||
|
||||
-- | Keyword/symbol ordering is determined by the unique ID.
|
||||
instance Ord TokSymbol where compare = compare `on` tsID
|
||||
|
||||
-- | Token with position.
|
||||
data Token
|
||||
= PT Posn Tok
|
||||
| Err Posn
|
||||
deriving (Eq, Show, Ord)
|
||||
|
||||
-- | Pretty print a position.
|
||||
printPosn :: Posn -> String
|
||||
printPosn (Pn _ l c) = "line " ++ show l ++ ", column " ++ show c
|
||||
|
||||
-- | Pretty print the position of the first token in the list.
|
||||
tokenPos :: [Token] -> String
|
||||
tokenPos (t:_) = printPosn (tokenPosn t)
|
||||
tokenPos [] = "end of file"
|
||||
|
||||
-- | Get the position of a token.
|
||||
tokenPosn :: Token -> Posn
|
||||
tokenPosn (PT p _) = p
|
||||
tokenPosn (Err p) = p
|
||||
|
||||
-- | Get line and column of a token.
|
||||
tokenLineCol :: Token -> (Int, Int)
|
||||
tokenLineCol = posLineCol . tokenPosn
|
||||
|
||||
-- | Get line and column of a position.
|
||||
posLineCol :: Posn -> (Int, Int)
|
||||
posLineCol (Pn _ l c) = (l,c)
|
||||
|
||||
-- | Convert a token into "position token" form.
|
||||
mkPosToken :: Token -> ((Int, Int), Data.Text.Text)
|
||||
mkPosToken t = (tokenLineCol t, tokenText t)
|
||||
|
||||
-- | Convert a token to its text.
|
||||
tokenText :: Token -> Data.Text.Text
|
||||
tokenText t = case t of
|
||||
PT _ (TS s _) -> s
|
||||
PT _ (TL s) -> Data.Text.pack (show s)
|
||||
PT _ (TI s) -> s
|
||||
PT _ (TV s) -> s
|
||||
PT _ (TD s) -> s
|
||||
PT _ (TC s) -> s
|
||||
Err _ -> Data.Text.pack "#error"
|
||||
PT _ (T_UIdent s) -> s
|
||||
|
||||
-- | Convert a token to a string.
|
||||
prToken :: Token -> String
|
||||
prToken t = Data.Text.unpack (tokenText t)
|
||||
|
||||
-- | Finite map from text to token organized as binary search tree.
|
||||
data BTree
|
||||
= N -- ^ Nil (leaf).
|
||||
| B Data.Text.Text Tok BTree BTree
|
||||
-- ^ Binary node.
|
||||
deriving (Show)
|
||||
|
||||
-- | Convert potential keyword into token or use fallback conversion.
|
||||
eitherResIdent :: (Data.Text.Text -> Tok) -> Data.Text.Text -> Tok
|
||||
eitherResIdent tv s = treeFind resWords
|
||||
where
|
||||
treeFind N = tv s
|
||||
treeFind (B a t left right) =
|
||||
case compare s a of
|
||||
LT -> treeFind left
|
||||
GT -> treeFind right
|
||||
EQ -> t
|
||||
|
||||
-- | The keywords and symbols of the language organized as binary search tree.
|
||||
resWords :: BTree
|
||||
resWords =
|
||||
b "Double" 11
|
||||
(b "." 6
|
||||
(b "*" 3 (b ")" 2 (b "(" 1 N N) N) (b "-" 5 (b "+" 4 N N) N))
|
||||
(b "=" 9 (b "<" 8 (b ":" 7 N N) N) (b "Char" 10 N N)))
|
||||
(b "then" 16
|
||||
(b "else" 14 (b "String" 13 (b "Int" 12 N N) N) (b "if" 15 N N))
|
||||
(b "\8594" 19
|
||||
(b "\955" 18 (b "\923" 17 N N) N) (b "\8704" 20 N N)))
|
||||
where
|
||||
b s n = B bs (TS bs n)
|
||||
where
|
||||
bs = Data.Text.pack s
|
||||
|
||||
-- | Unquote string literal.
|
||||
unescapeInitTail :: Data.Text.Text -> Data.Text.Text
|
||||
unescapeInitTail = Data.Text.pack . unesc . tail . Data.Text.unpack
|
||||
where
|
||||
unesc s = case s of
|
||||
'\\':c:cs | elem c ['\"', '\\', '\''] -> c : unesc cs
|
||||
'\\':'n':cs -> '\n' : unesc cs
|
||||
'\\':'t':cs -> '\t' : unesc cs
|
||||
'\\':'r':cs -> '\r' : unesc cs
|
||||
'\\':'f':cs -> '\f' : unesc cs
|
||||
'"':[] -> []
|
||||
c:cs -> c : unesc cs
|
||||
_ -> []
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Alex wrapper code.
|
||||
-- A modified "posn" wrapper.
|
||||
-------------------------------------------------------------------
|
||||
|
||||
data Posn = Pn !Int !Int !Int
|
||||
deriving (Eq, Show, Ord)
|
||||
|
||||
alexStartPos :: Posn
|
||||
alexStartPos = Pn 0 1 1
|
||||
|
||||
alexMove :: Posn -> Char -> Posn
|
||||
alexMove (Pn a l c) '\t' = Pn (a+1) l (((c+7) `div` 8)*8+1)
|
||||
alexMove (Pn a l c) '\n' = Pn (a+1) (l+1) 1
|
||||
alexMove (Pn a l c) _ = Pn (a+1) l (c+1)
|
||||
|
||||
type Byte = Word8
|
||||
|
||||
type AlexInput = (Posn, -- current position,
|
||||
Char, -- previous char
|
||||
[Byte], -- pending bytes on the current char
|
||||
Data.Text.Text) -- current input string
|
||||
|
||||
tokens :: Data.Text.Text -> [Token]
|
||||
tokens str = go (alexStartPos, '\n', [], str)
|
||||
where
|
||||
go :: AlexInput -> [Token]
|
||||
go inp@(pos, _, _, str) =
|
||||
case alexScan inp 0 of
|
||||
AlexEOF -> []
|
||||
AlexError (pos, _, _, _) -> [Err pos]
|
||||
AlexSkip inp' len -> go inp'
|
||||
AlexToken inp' len act -> act pos (Data.Text.take len str) : (go inp')
|
||||
|
||||
alexGetByte :: AlexInput -> Maybe (Byte,AlexInput)
|
||||
alexGetByte (p, c, (b:bs), s) = Just (b, (p, c, bs, s))
|
||||
alexGetByte (p, _, [], s) =
|
||||
case Data.Text.uncons s of
|
||||
Nothing -> Nothing
|
||||
Just (c,s) ->
|
||||
let p' = alexMove p c
|
||||
(b:bs) = utf8Encode c
|
||||
in p' `seq` Just (b, (p', c, bs, s))
|
||||
|
||||
alexInputPrevChar :: AlexInput -> Char
|
||||
alexInputPrevChar (p, c, bs, s) = c
|
||||
|
||||
-- | Encode a Haskell String to a list of Word8 values, in UTF8 format.
|
||||
utf8Encode :: Char -> [Word8]
|
||||
utf8Encode = map fromIntegral . go . ord
|
||||
where
|
||||
go oc
|
||||
| oc <= 0x7f = [oc]
|
||||
|
||||
| oc <= 0x7ff = [ 0xc0 + (oc `Data.Bits.shiftR` 6)
|
||||
, 0x80 + oc Data.Bits..&. 0x3f
|
||||
]
|
||||
|
||||
| oc <= 0xffff = [ 0xe0 + (oc `Data.Bits.shiftR` 12)
|
||||
, 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f)
|
||||
, 0x80 + oc Data.Bits..&. 0x3f
|
||||
]
|
||||
| otherwise = [ 0xf0 + (oc `Data.Bits.shiftR` 18)
|
||||
, 0x80 + ((oc `Data.Bits.shiftR` 12) Data.Bits..&. 0x3f)
|
||||
, 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f)
|
||||
, 0x80 + oc Data.Bits..&. 0x3f
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
-- File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
-- Test for Agda binding of parser. Requires Agda >= 2.5.4.
|
||||
|
||||
module Alisaie.Main where
|
||||
open import Alisaie.IOLib
|
||||
open import Alisaie.AST using (printProgram)
|
||||
open import Alisaie.Parser using (Err; parseProgram)
|
||||
|
||||
main : IO ⊤
|
||||
main = do
|
||||
file ∷ [] ← getArgs where
|
||||
_ → do
|
||||
putStrLn "usage: Main <SourceFile>"
|
||||
exitFailure
|
||||
Err.ok result ← parseProgram <$> readFiniteFile file where
|
||||
Err.bad msg → do
|
||||
putStrLn "PARSE FAILED\n"
|
||||
putStrLn (stringFromList msg)
|
||||
exitFailure
|
||||
putStrLn "PARSE SUCCESSFUL\n"
|
||||
putStrLn (printProgram result)
|
||||
+1272
File diff suppressed because it is too large.
Load diff
+2041
File diff suppressed because it is too large.
Load diff
+182
@@ -0,0 +1,182 @@
|
||||
-- -*- haskell -*- File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
-- Parser definition for use with Happy
|
||||
{
|
||||
{-# OPTIONS_GHC -Wno-incomplete-patterns -Wno-overlapping-patterns #-}
|
||||
{-# LANGUAGE PatternSynonyms #-}
|
||||
|
||||
module Alisaie.Par
|
||||
( happyError
|
||||
, myLexer
|
||||
, pProgram
|
||||
, pDefinition
|
||||
, pKind
|
||||
, pKind1
|
||||
, pType1
|
||||
, pType
|
||||
, pListDefinition
|
||||
, pListIdent
|
||||
, pExp4
|
||||
, pExp2
|
||||
, pExp1
|
||||
, pExp
|
||||
, pExp3
|
||||
) where
|
||||
|
||||
import Prelude
|
||||
|
||||
import qualified Alisaie.Abs
|
||||
import Alisaie.Lex
|
||||
import qualified Data.Text
|
||||
|
||||
}
|
||||
|
||||
%name pProgram Program
|
||||
%name pDefinition Definition
|
||||
%name pKind Kind
|
||||
%name pKind1 Kind1
|
||||
%name pType1 Type1
|
||||
%name pType Type
|
||||
%name pListDefinition ListDefinition
|
||||
%name pListIdent ListIdent
|
||||
%name pExp4 Exp4
|
||||
%name pExp2 Exp2
|
||||
%name pExp1 Exp1
|
||||
%name pExp Exp
|
||||
%name pExp3 Exp3
|
||||
-- no lexer declaration
|
||||
%monad { Err } { (>>=) } { return }
|
||||
%tokentype {Token}
|
||||
%token
|
||||
'(' { PT _ (TS _ 1) }
|
||||
')' { PT _ (TS _ 2) }
|
||||
'*' { PT _ (TS _ 3) }
|
||||
'+' { PT _ (TS _ 4) }
|
||||
'-' { PT _ (TS _ 5) }
|
||||
'.' { PT _ (TS _ 6) }
|
||||
':' { PT _ (TS _ 7) }
|
||||
'<' { PT _ (TS _ 8) }
|
||||
'=' { PT _ (TS _ 9) }
|
||||
'Char' { PT _ (TS _ 10) }
|
||||
'Double' { PT _ (TS _ 11) }
|
||||
'Int' { PT _ (TS _ 12) }
|
||||
'String' { PT _ (TS _ 13) }
|
||||
'else' { PT _ (TS _ 14) }
|
||||
'if' { PT _ (TS _ 15) }
|
||||
'then' { PT _ (TS _ 16) }
|
||||
'Λ' { PT _ (TS _ 17) }
|
||||
'λ' { PT _ (TS _ 18) }
|
||||
'→' { PT _ (TS _ 19) }
|
||||
'∀' { PT _ (TS _ 20) }
|
||||
L_Ident { PT _ (TV $$) }
|
||||
L_charac { PT _ (TC $$) }
|
||||
L_doubl { PT _ (TD $$) }
|
||||
L_integ { PT _ (TI $$) }
|
||||
L_quoted { PT _ (TL $$) }
|
||||
L_UIdent { PT _ (T_UIdent $$) }
|
||||
|
||||
%%
|
||||
|
||||
Ident :: { Alisaie.Abs.Ident }
|
||||
Ident : L_Ident { Alisaie.Abs.Ident $1 }
|
||||
|
||||
Char :: { Char }
|
||||
Char : L_charac { (read (Data.Text.unpack $1)) :: Char }
|
||||
|
||||
Double :: { Double }
|
||||
Double : L_doubl { (read (Data.Text.unpack $1)) :: Double }
|
||||
|
||||
Integer :: { Integer }
|
||||
Integer : L_integ { (read (Data.Text.unpack $1)) :: Integer }
|
||||
|
||||
String :: { String }
|
||||
String : L_quoted { (Data.Text.unpack $1) }
|
||||
|
||||
UIdent :: { Alisaie.Abs.UIdent }
|
||||
UIdent : L_UIdent { Alisaie.Abs.UIdent $1 }
|
||||
|
||||
Program :: { Alisaie.Abs.Program }
|
||||
Program : ListDefinition { Alisaie.Abs.Prog $1 }
|
||||
|
||||
Definition :: { Alisaie.Abs.Definition }
|
||||
Definition
|
||||
: Ident ':' Type Ident ListIdent '=' Exp { Alisaie.Abs.Def $1 $3 $4 $5 $7 }
|
||||
|
||||
Kind :: { Alisaie.Abs.Kind }
|
||||
Kind : '*' { Alisaie.Abs.KStar }
|
||||
|
||||
Kind1 :: { Alisaie.Abs.Kind }
|
||||
Kind1 : Kind '→' Kind { Alisaie.Abs.KArr $1 $3 } | Kind { $1 }
|
||||
|
||||
Type1 :: { Alisaie.Abs.Type }
|
||||
Type1
|
||||
: 'String' { Alisaie.Abs.TString }
|
||||
| 'Int' { Alisaie.Abs.TInt }
|
||||
| 'Double' { Alisaie.Abs.TDouble }
|
||||
| 'Char' { Alisaie.Abs.TChar }
|
||||
| UIdent { Alisaie.Abs.TCustom $1 }
|
||||
| '(' Type ')' { $2 }
|
||||
|
||||
Type :: { Alisaie.Abs.Type }
|
||||
Type
|
||||
: Type1 '→' Type { Alisaie.Abs.TArr $1 $3 }
|
||||
| '∀' Ident ':' Kind '.' Type { Alisaie.Abs.TForall $2 $4 $6 }
|
||||
| 'λ' Ident ':' Kind '.' Type { Alisaie.Abs.TLambda $2 $4 $6 }
|
||||
| Type1 { $1 }
|
||||
|
||||
ListDefinition :: { [Alisaie.Abs.Definition] }
|
||||
ListDefinition
|
||||
: {- empty -} { [] } | Definition ListDefinition { (:) $1 $2 }
|
||||
|
||||
ListIdent :: { [Alisaie.Abs.Ident] }
|
||||
ListIdent : {- empty -} { [] } | Ident ListIdent { (:) $1 $2 }
|
||||
|
||||
Exp4 :: { Alisaie.Abs.Exp }
|
||||
Exp4
|
||||
: Ident { Alisaie.Abs.EVar $1 }
|
||||
| Integer { Alisaie.Abs.EInt $1 }
|
||||
| Double { Alisaie.Abs.EDouble $1 }
|
||||
| Char { Alisaie.Abs.EChar $1 }
|
||||
| String { Alisaie.Abs.EText $1 }
|
||||
| '(' Exp ')' { $2 }
|
||||
|
||||
Exp2 :: { Alisaie.Abs.Exp }
|
||||
Exp2
|
||||
: Exp2 Exp3 { Alisaie.Abs.EApp $1 $2 }
|
||||
| Exp2 Type { Alisaie.Abs.ETApp $1 $2 }
|
||||
| Exp3 { $1 }
|
||||
|
||||
Exp1 :: { Alisaie.Abs.Exp }
|
||||
Exp1
|
||||
: Exp1 '+' Exp2 { Alisaie.Abs.EAdd $1 $3 }
|
||||
| Exp1 '-' Exp2 { Alisaie.Abs.ESub $1 $3 }
|
||||
| Exp1 '<' Exp2 { Alisaie.Abs.ELt $1 $3 }
|
||||
| Exp2 { $1 }
|
||||
|
||||
Exp :: { Alisaie.Abs.Exp }
|
||||
Exp
|
||||
: 'if' Exp 'then' Exp 'else' Exp { Alisaie.Abs.EIf $2 $4 $6 }
|
||||
| 'Λ' Ident ':' Kind '.' Exp { Alisaie.Abs.ETAbs $2 $4 $6 }
|
||||
| 'λ' Ident ':' Type '.' Exp { Alisaie.Abs.EAbs $2 $4 $6 }
|
||||
| Exp1 { $1 }
|
||||
|
||||
Exp3 :: { Alisaie.Abs.Exp }
|
||||
Exp3 : Exp4 { $1 }
|
||||
|
||||
{
|
||||
|
||||
type Err = Either String
|
||||
|
||||
happyError :: [Token] -> Err a
|
||||
happyError ts = Left $
|
||||
"syntax error at " ++ tokenPos ts ++
|
||||
case ts of
|
||||
[] -> []
|
||||
[Err _] -> " due to lexer error"
|
||||
t:_ -> " before `" ++ (prToken t) ++ "'"
|
||||
|
||||
myLexer :: Data.Text.Text -> [Token]
|
||||
myLexer = tokens
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
-- File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
-- Agda bindings for the Haskell parsers.
|
||||
|
||||
module Alisaie.Parser where
|
||||
|
||||
open import Agda.Builtin.Char using (Char)
|
||||
open import Agda.Builtin.List using ([]; _∷_) renaming (List to #List)
|
||||
open import Agda.Builtin.String using () renaming
|
||||
( String to #String
|
||||
; primStringFromList to #stringFromList
|
||||
)
|
||||
|
||||
open import Alisaie.AST using
|
||||
( Program
|
||||
; Definition
|
||||
; Kind
|
||||
; Type
|
||||
; Ident
|
||||
; Exp
|
||||
)
|
||||
|
||||
{-# FOREIGN GHC import Prelude (Bool, Char, Double, Integer, String, (.)) #-}
|
||||
{-# FOREIGN GHC import qualified Data.Text #-}
|
||||
{-# FOREIGN GHC import qualified Alisaie.ErrM #-}
|
||||
{-# FOREIGN GHC import Alisaie.Par #-}
|
||||
|
||||
-- Error monad of BNFC
|
||||
|
||||
data Err A : Set where
|
||||
ok : A → Err A
|
||||
bad : #List Char → Err A
|
||||
|
||||
{-# COMPILE GHC Err = data Alisaie.ErrM.Err
|
||||
( Alisaie.ErrM.Ok
|
||||
| Alisaie.ErrM.Bad
|
||||
) #-}
|
||||
|
||||
-- Happy parsers
|
||||
|
||||
postulate
|
||||
parseProgram : #String → Err Program
|
||||
parseDefinition : #String → Err Definition
|
||||
parseKind : #String → Err Kind
|
||||
parseKind1 : #String → Err Kind
|
||||
parseType1 : #String → Err Type
|
||||
parseType : #String → Err Type
|
||||
parseListDefinition : #String → Err (#List Definition)
|
||||
parseListIdent : #String → Err (#List Ident)
|
||||
parseExp4 : #String → Err Exp
|
||||
parseExp2 : #String → Err Exp
|
||||
parseExp1 : #String → Err Exp
|
||||
parseExp : #String → Err Exp
|
||||
parseExp3 : #String → Err Exp
|
||||
|
||||
{-# COMPILE GHC parseProgram = pProgram . myLexer #-}
|
||||
{-# COMPILE GHC parseDefinition = pDefinition . myLexer #-}
|
||||
{-# COMPILE GHC parseKind = pKind . myLexer #-}
|
||||
{-# COMPILE GHC parseKind1 = pKind1 . myLexer #-}
|
||||
{-# COMPILE GHC parseType1 = pType1 . myLexer #-}
|
||||
{-# COMPILE GHC parseType = pType . myLexer #-}
|
||||
{-# COMPILE GHC parseListDefinition = pListDefinition . myLexer #-}
|
||||
{-# COMPILE GHC parseListIdent = pListIdent . myLexer #-}
|
||||
{-# COMPILE GHC parseExp4 = pExp4 . myLexer #-}
|
||||
{-# COMPILE GHC parseExp2 = pExp2 . myLexer #-}
|
||||
{-# COMPILE GHC parseExp1 = pExp1 . myLexer #-}
|
||||
{-# COMPILE GHC parseExp = pExp . myLexer #-}
|
||||
{-# COMPILE GHC parseExp3 = pExp3 . myLexer #-}
|
||||
@@ -0,0 +1,188 @@
|
||||
-- File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
|
||||
-- | Pretty-printer for Alisaie.
|
||||
|
||||
module Alisaie.Print where
|
||||
|
||||
import Prelude
|
||||
( ($), (.)
|
||||
, Bool(..), (==), (<)
|
||||
, Int, Integer, Double, (+), (-), (*)
|
||||
, String, (++)
|
||||
, ShowS, showChar, showString
|
||||
, all, elem, foldr, id, map, null, replicate, shows, span
|
||||
)
|
||||
import Data.Char ( Char, isSpace )
|
||||
import qualified Alisaie.Abs
|
||||
import qualified Data.Text
|
||||
|
||||
-- | The top-level printing method.
|
||||
|
||||
printTree :: Print a => a -> String
|
||||
printTree = render . prt 0
|
||||
|
||||
type Doc = [ShowS] -> [ShowS]
|
||||
|
||||
doc :: ShowS -> Doc
|
||||
doc = (:)
|
||||
|
||||
render :: Doc -> String
|
||||
render d = rend 0 False (map ($ "") $ d []) ""
|
||||
where
|
||||
rend
|
||||
:: Int -- ^ Indentation level.
|
||||
-> Bool -- ^ Pending indentation to be output before next character?
|
||||
-> [String]
|
||||
-> ShowS
|
||||
rend i p = \case
|
||||
"[" :ts -> char '[' . rend i False ts
|
||||
"(" :ts -> char '(' . rend i False ts
|
||||
"{" :ts -> onNewLine i p . showChar '{' . new (i+1) ts
|
||||
"}" : ";":ts -> onNewLine (i-1) p . showString "};" . new (i-1) ts
|
||||
"}" :ts -> onNewLine (i-1) p . showChar '}' . new (i-1) ts
|
||||
[";"] -> char ';'
|
||||
";" :ts -> char ';' . new i ts
|
||||
t : ts@(s:_) | closingOrPunctuation s
|
||||
-> pending . showString t . rend i False ts
|
||||
t :ts -> pending . space t . rend i False ts
|
||||
[] -> id
|
||||
where
|
||||
-- Output character after pending indentation.
|
||||
char :: Char -> ShowS
|
||||
char c = pending . showChar c
|
||||
|
||||
-- Output pending indentation.
|
||||
pending :: ShowS
|
||||
pending = if p then indent i else id
|
||||
|
||||
-- Indentation (spaces) for given indentation level.
|
||||
indent :: Int -> ShowS
|
||||
indent i = replicateS (2*i) (showChar ' ')
|
||||
|
||||
-- Continue rendering in new line with new indentation.
|
||||
new :: Int -> [String] -> ShowS
|
||||
new j ts = showChar '\n' . rend j True ts
|
||||
|
||||
-- Make sure we are on a fresh line.
|
||||
onNewLine :: Int -> Bool -> ShowS
|
||||
onNewLine i p = (if p then id else showChar '\n') . indent i
|
||||
|
||||
-- Separate given string from following text by a space (if needed).
|
||||
space :: String -> ShowS
|
||||
space t s =
|
||||
case (all isSpace t, null spc, null rest) of
|
||||
(True , _ , True ) -> [] -- remove trailing space
|
||||
(False, _ , True ) -> t -- remove trailing space
|
||||
(False, True, False) -> t ++ ' ' : s -- add space if none
|
||||
_ -> t ++ s
|
||||
where
|
||||
(spc, rest) = span isSpace s
|
||||
|
||||
closingOrPunctuation :: String -> Bool
|
||||
closingOrPunctuation [c] = c `elem` closerOrPunct
|
||||
closingOrPunctuation _ = False
|
||||
|
||||
closerOrPunct :: String
|
||||
closerOrPunct = ")],;"
|
||||
|
||||
parenth :: Doc -> Doc
|
||||
parenth ss = doc (showChar '(') . ss . doc (showChar ')')
|
||||
|
||||
concatS :: [ShowS] -> ShowS
|
||||
concatS = foldr (.) id
|
||||
|
||||
concatD :: [Doc] -> Doc
|
||||
concatD = foldr (.) id
|
||||
|
||||
replicateS :: Int -> ShowS -> ShowS
|
||||
replicateS n f = concatS (replicate n f)
|
||||
|
||||
-- | The printer class does the job.
|
||||
|
||||
class Print a where
|
||||
prt :: Int -> a -> Doc
|
||||
|
||||
instance {-# OVERLAPPABLE #-} Print a => Print [a] where
|
||||
prt i = concatD . map (prt i)
|
||||
|
||||
instance Print Char where
|
||||
prt _ c = doc (showChar '\'' . mkEsc '\'' c . showChar '\'')
|
||||
|
||||
instance Print String where
|
||||
prt _ = printString
|
||||
|
||||
printString :: String -> Doc
|
||||
printString s = doc (showChar '"' . concatS (map (mkEsc '"') s) . showChar '"')
|
||||
|
||||
mkEsc :: Char -> Char -> ShowS
|
||||
mkEsc q = \case
|
||||
s | s == q -> showChar '\\' . showChar s
|
||||
'\\' -> showString "\\\\"
|
||||
'\n' -> showString "\\n"
|
||||
'\t' -> showString "\\t"
|
||||
s -> showChar s
|
||||
|
||||
prPrec :: Int -> Int -> Doc -> Doc
|
||||
prPrec i j = if j < i then parenth else id
|
||||
|
||||
instance Print Integer where
|
||||
prt _ x = doc (shows x)
|
||||
|
||||
instance Print Double where
|
||||
prt _ x = doc (shows x)
|
||||
|
||||
instance Print Alisaie.Abs.Ident where
|
||||
prt _ (Alisaie.Abs.Ident i) = doc $ showString (Data.Text.unpack i)
|
||||
instance Print Alisaie.Abs.UIdent where
|
||||
prt _ (Alisaie.Abs.UIdent i) = doc $ showString (Data.Text.unpack i)
|
||||
instance Print Alisaie.Abs.Program where
|
||||
prt i = \case
|
||||
Alisaie.Abs.Prog definitions -> prPrec i 0 (concatD [prt 0 definitions])
|
||||
|
||||
instance Print Alisaie.Abs.Definition where
|
||||
prt i = \case
|
||||
Alisaie.Abs.Def id_1 type_ id_2 ids exp -> prPrec i 0 (concatD [prt 0 id_1, doc (showString ":"), prt 0 type_, prt 0 id_2, prt 0 ids, doc (showString "="), prt 0 exp])
|
||||
|
||||
instance Print Alisaie.Abs.Kind where
|
||||
prt i = \case
|
||||
Alisaie.Abs.KStar -> prPrec i 0 (concatD [doc (showString "*")])
|
||||
Alisaie.Abs.KArr kind1 kind2 -> prPrec i 1 (concatD [prt 0 kind1, doc (showString "\8594"), prt 0 kind2])
|
||||
|
||||
instance Print Alisaie.Abs.Type where
|
||||
prt i = \case
|
||||
Alisaie.Abs.TString -> prPrec i 1 (concatD [doc (showString "String")])
|
||||
Alisaie.Abs.TInt -> prPrec i 1 (concatD [doc (showString "Int")])
|
||||
Alisaie.Abs.TDouble -> prPrec i 1 (concatD [doc (showString "Double")])
|
||||
Alisaie.Abs.TChar -> prPrec i 1 (concatD [doc (showString "Char")])
|
||||
Alisaie.Abs.TCustom uident -> prPrec i 1 (concatD [prt 0 uident])
|
||||
Alisaie.Abs.TArr type_1 type_2 -> prPrec i 0 (concatD [prt 1 type_1, doc (showString "\8594"), prt 0 type_2])
|
||||
Alisaie.Abs.TForall id_ kind type_ -> prPrec i 0 (concatD [doc (showString "\8704"), prt 0 id_, doc (showString ":"), prt 0 kind, doc (showString "."), prt 0 type_])
|
||||
Alisaie.Abs.TLambda id_ kind type_ -> prPrec i 0 (concatD [doc (showString "\955"), prt 0 id_, doc (showString ":"), prt 0 kind, doc (showString "."), prt 0 type_])
|
||||
|
||||
instance Print [Alisaie.Abs.Definition] where
|
||||
prt _ [] = concatD []
|
||||
prt _ (x:xs) = concatD [prt 0 x, prt 0 xs]
|
||||
|
||||
instance Print [Alisaie.Abs.Ident] where
|
||||
prt _ [] = concatD []
|
||||
prt _ (x:xs) = concatD [prt 0 x, prt 0 xs]
|
||||
|
||||
instance Print Alisaie.Abs.Exp where
|
||||
prt i = \case
|
||||
Alisaie.Abs.EVar id_ -> prPrec i 4 (concatD [prt 0 id_])
|
||||
Alisaie.Abs.EInt n -> prPrec i 4 (concatD [prt 0 n])
|
||||
Alisaie.Abs.EDouble d -> prPrec i 4 (concatD [prt 0 d])
|
||||
Alisaie.Abs.EChar c -> prPrec i 4 (concatD [prt 0 c])
|
||||
Alisaie.Abs.EText str -> prPrec i 4 (concatD [printString str])
|
||||
Alisaie.Abs.EApp exp1 exp2 -> prPrec i 2 (concatD [prt 2 exp1, prt 3 exp2])
|
||||
Alisaie.Abs.ETApp exp type_ -> prPrec i 2 (concatD [prt 2 exp, prt 0 type_])
|
||||
Alisaie.Abs.EAdd exp1 exp2 -> prPrec i 1 (concatD [prt 1 exp1, doc (showString "+"), prt 2 exp2])
|
||||
Alisaie.Abs.ESub exp1 exp2 -> prPrec i 1 (concatD [prt 1 exp1, doc (showString "-"), prt 2 exp2])
|
||||
Alisaie.Abs.ELt exp1 exp2 -> prPrec i 1 (concatD [prt 1 exp1, doc (showString "<"), prt 2 exp2])
|
||||
Alisaie.Abs.EIf exp1 exp2 exp3 -> prPrec i 0 (concatD [doc (showString "if"), prt 0 exp1, doc (showString "then"), prt 0 exp2, doc (showString "else"), prt 0 exp3])
|
||||
Alisaie.Abs.ETAbs id_ kind exp -> prPrec i 0 (concatD [doc (showString "\923"), prt 0 id_, doc (showString ":"), prt 0 kind, doc (showString "."), prt 0 exp])
|
||||
Alisaie.Abs.EAbs id_ type_ exp -> prPrec i 0 (concatD [doc (showString "\955"), prt 0 id_, doc (showString ":"), prt 0 type_, doc (showString "."), prt 0 exp])
|
||||
@@ -0,0 +1,64 @@
|
||||
-- File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
-- Templates for pattern matching on abstract syntax
|
||||
|
||||
{-# OPTIONS_GHC -Wno-unused-matches #-}
|
||||
|
||||
module Alisaie.Skel where
|
||||
|
||||
import Prelude (($), Either(..), String, (++), Show, show)
|
||||
import qualified Alisaie.Abs
|
||||
|
||||
type Err = Either String
|
||||
type Result = Err String
|
||||
|
||||
failure :: Show a => a -> Result
|
||||
failure x = Left $ "Undefined case: " ++ show x
|
||||
|
||||
transIdent :: Alisaie.Abs.Ident -> Result
|
||||
transIdent x = case x of
|
||||
Alisaie.Abs.Ident string -> failure x
|
||||
|
||||
transUIdent :: Alisaie.Abs.UIdent -> Result
|
||||
transUIdent x = case x of
|
||||
Alisaie.Abs.UIdent string -> failure x
|
||||
|
||||
transProgram :: Alisaie.Abs.Program -> Result
|
||||
transProgram x = case x of
|
||||
Alisaie.Abs.Prog definitions -> failure x
|
||||
|
||||
transDefinition :: Alisaie.Abs.Definition -> Result
|
||||
transDefinition x = case x of
|
||||
Alisaie.Abs.Def ident1 type_ ident2 idents exp -> failure x
|
||||
|
||||
transKind :: Alisaie.Abs.Kind -> Result
|
||||
transKind x = case x of
|
||||
Alisaie.Abs.KStar -> failure x
|
||||
Alisaie.Abs.KArr kind1 kind2 -> failure x
|
||||
|
||||
transType :: Alisaie.Abs.Type -> Result
|
||||
transType x = case x of
|
||||
Alisaie.Abs.TString -> failure x
|
||||
Alisaie.Abs.TInt -> failure x
|
||||
Alisaie.Abs.TDouble -> failure x
|
||||
Alisaie.Abs.TChar -> failure x
|
||||
Alisaie.Abs.TCustom uident -> failure x
|
||||
Alisaie.Abs.TArr type_1 type_2 -> failure x
|
||||
Alisaie.Abs.TForall ident kind type_ -> failure x
|
||||
Alisaie.Abs.TLambda ident kind type_ -> failure x
|
||||
|
||||
transExp :: Alisaie.Abs.Exp -> Result
|
||||
transExp x = case x of
|
||||
Alisaie.Abs.EVar ident -> failure x
|
||||
Alisaie.Abs.EInt integer -> failure x
|
||||
Alisaie.Abs.EDouble double -> failure x
|
||||
Alisaie.Abs.EChar char -> failure x
|
||||
Alisaie.Abs.EText string -> failure x
|
||||
Alisaie.Abs.EApp exp1 exp2 -> failure x
|
||||
Alisaie.Abs.ETApp exp type_ -> failure x
|
||||
Alisaie.Abs.EAdd exp1 exp2 -> failure x
|
||||
Alisaie.Abs.ESub exp1 exp2 -> failure x
|
||||
Alisaie.Abs.ELt exp1 exp2 -> failure x
|
||||
Alisaie.Abs.EIf exp1 exp2 exp3 -> failure x
|
||||
Alisaie.Abs.ETAbs ident kind exp -> failure x
|
||||
Alisaie.Abs.EAbs ident type_ exp -> failure x
|
||||
@@ -0,0 +1,77 @@
|
||||
-- File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
-- | Program to test parser.
|
||||
|
||||
module Main where
|
||||
|
||||
import Prelude
|
||||
( ($), (.)
|
||||
, Either(..)
|
||||
, Int, (>)
|
||||
, String, (++), concat, unlines
|
||||
, Show, show
|
||||
, IO, (>>), (>>=), mapM_, putStrLn
|
||||
, FilePath
|
||||
)
|
||||
import Data.Text.IO ( getContents, readFile )
|
||||
import qualified Data.Text
|
||||
import System.Environment ( getArgs )
|
||||
import System.Exit ( exitFailure )
|
||||
import Control.Monad ( when )
|
||||
|
||||
import Alisaie.Abs ()
|
||||
import Alisaie.Lex ( Token, mkPosToken )
|
||||
import Alisaie.Par ( pProgram, myLexer )
|
||||
import Alisaie.Print ( Print, printTree )
|
||||
import Alisaie.Skel ()
|
||||
|
||||
type Err = Either String
|
||||
type ParseFun a = [Token] -> Err a
|
||||
type Verbosity = Int
|
||||
|
||||
putStrV :: Verbosity -> String -> IO ()
|
||||
putStrV v s = when (v > 1) $ putStrLn s
|
||||
|
||||
runFile :: (Print a, Show a) => Verbosity -> ParseFun a -> FilePath -> IO ()
|
||||
runFile v p f = putStrLn f >> readFile f >>= run v p
|
||||
|
||||
run :: (Print a, Show a) => Verbosity -> ParseFun a -> Data.Text.Text -> IO ()
|
||||
run v p s =
|
||||
case p ts of
|
||||
Left err -> do
|
||||
putStrLn "\nParse Failed...\n"
|
||||
putStrV v "Tokens:"
|
||||
mapM_ (putStrV v . showPosToken . mkPosToken) ts
|
||||
putStrLn err
|
||||
exitFailure
|
||||
Right tree -> do
|
||||
putStrLn "\nParse Successful!"
|
||||
showTree v tree
|
||||
where
|
||||
ts = myLexer s
|
||||
showPosToken ((l,c),t) = concat [ show l, ":", show c, "\t", show t ]
|
||||
|
||||
showTree :: (Show a, Print a) => Int -> a -> IO ()
|
||||
showTree v tree = do
|
||||
putStrV v $ "\n[Abstract Syntax]\n\n" ++ show tree
|
||||
putStrV v $ "\n[Linearized tree]\n\n" ++ printTree tree
|
||||
|
||||
usage :: IO ()
|
||||
usage = do
|
||||
putStrLn $ unlines
|
||||
[ "usage: Call with one of the following argument combinations:"
|
||||
, " --help Display this help message."
|
||||
, " (no arguments) Parse stdin verbosely."
|
||||
, " (files) Parse content of files verbosely."
|
||||
, " -s (files) Silent mode. Parse content of files silently."
|
||||
]
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
args <- getArgs
|
||||
case args of
|
||||
["--help"] -> usage
|
||||
[] -> getContents >>= run 2 pProgram
|
||||
"-s":fs -> mapM_ (runFile 0 pProgram) fs
|
||||
fs -> mapM_ (runFile 2 pProgram) fs
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
## File generated by the BNF Converter (bnfc 2.9.6.1).
|
||||
|
||||
# Makefile for building the parser and test program.
|
||||
|
||||
AGDA = agda
|
||||
GHC = ghc
|
||||
HAPPY = happy
|
||||
HAPPY_OPTS = --array --info --ghc --coerce
|
||||
ALEX = alex
|
||||
ALEX_OPTS = --ghc
|
||||
|
||||
# List of goals not corresponding to file names.
|
||||
|
||||
.PHONY : all clean distclean
|
||||
|
||||
# Default goal.
|
||||
|
||||
all : Alisaie/Test Main
|
||||
|
||||
# Rules for building the parser.
|
||||
|
||||
Alisaie/Abs.hs Alisaie/Lex.x Alisaie/Par.y Alisaie/Print.hs Alisaie/Test.hs Alisaie/AST.agda Alisaie/Parser.agda Alisaie/IOLib.agda Alisaie/Main.agda : Alisaie.cf
|
||||
bnfc --haskell -d --agda Alisaie.cf
|
||||
|
||||
%.hs : %.y
|
||||
${HAPPY} ${HAPPY_OPTS} $<
|
||||
|
||||
%.hs : %.x
|
||||
${ALEX} ${ALEX_OPTS} $<
|
||||
|
||||
Alisaie/Test : Alisaie/Abs.hs Alisaie/Lex.hs Alisaie/Par.hs Alisaie/Print.hs Alisaie/Test.hs
|
||||
${GHC} ${GHC_OPTS} $@
|
||||
|
||||
Main : Alisaie/Main.agda Alisaie/AST.agda Alisaie/Parser.agda Alisaie/IOLib.agda Alisaie/ErrM.hs Alisaie/Lex.hs Alisaie/Par.hs Alisaie/Print.hs
|
||||
${AGDA} --no-libraries --ghc --ghc-flag=-Wwarn $<
|
||||
|
||||
# Rules for cleaning generated files.
|
||||
|
||||
clean :
|
||||
-rm -f Alisaie/*.hi Alisaie/*.o Alisaie/*.log Alisaie/*.aux Alisaie/*.dvi Alisaie/*.agdai
|
||||
-rm -rf MAlonzo
|
||||
|
||||
distclean : clean
|
||||
-rm -f Alisaie/Abs.hs Alisaie/Abs.hs.bak Alisaie/ComposOp.hs Alisaie/ComposOp.hs.bak Alisaie/Doc.txt Alisaie/Doc.txt.bak Alisaie/ErrM.hs Alisaie/ErrM.hs.bak Alisaie/Layout.hs Alisaie/Layout.hs.bak Alisaie/Lex.x Alisaie/Lex.x.bak Alisaie/Par.y Alisaie/Par.y.bak Alisaie/Print.hs Alisaie/Print.hs.bak Alisaie/Skel.hs Alisaie/Skel.hs.bak Alisaie/Test.hs Alisaie/Test.hs.bak Alisaie/XML.hs Alisaie/XML.hs.bak Alisaie/AST.agda Alisaie/AST.agda.bak Alisaie/Parser.agda Alisaie/Parser.agda.bak Alisaie/IOLib.agda Alisaie/IOLib.agda.bak Alisaie/Main.agda Alisaie/Main.agda.bak Alisaie/Alisaie.dtd Alisaie/Alisaie.dtd.bak Alisaie/Test Alisaie/Lex.hs Alisaie/Par.hs Alisaie/Par.info Alisaie/ParData.hs Main Makefile
|
||||
-rmdir -p Alisaie/
|
||||
|
||||
# EOF
|
||||
@@ -0,0 +1,2 @@
|
||||
main : IO ()
|
||||
main = putStrLn "Hejsan"
|
||||
Generated
+61
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1763759067,
|
||||
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1764242076,
|
||||
"narHash": "sha256-sKoIWfnijJ0+9e4wRvIgm/HgE27bzwQxcEmo2J/gNpI=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2fad6eac6077f03fe109c4d4eb171cf96791faa4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1761765539,
|
||||
"narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "719359f4562934ae99f5443f20aa06c2ffff91fc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
description = "Alisaie";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
};
|
||||
|
||||
outputs = inputs@{ nixpkgs, flake-parts, ... }:
|
||||
flake-parts.lib.mkFlake {inherit inputs;} {
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
];
|
||||
|
||||
perSystem = {self', pkgs, system, ...}: {
|
||||
|
||||
# packages.default = self'.packages.alisaie;
|
||||
# packages.alisaie = pkgs.stdenv.mkDerivation {
|
||||
# pname = "Alisaie";
|
||||
# version = "0.0.1";
|
||||
|
||||
# src = ./.;
|
||||
|
||||
# nativeBuildInputs = with pkgs; [ ];
|
||||
# buildInputs = [ ];
|
||||
|
||||
# };
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
(agda.withPackages (p: with p; [ standard-library ]))
|
||||
(haskellPackages.BNFC)
|
||||
(haskellPackages.alex)
|
||||
(haskellPackages.happy)
|
||||
];
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user