Haha
This commit is contained in:
11
.gitignore
vendored
11
.gitignore
vendored
@ -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
Alisaie.cf
Normal file
44
Alisaie.cf
Normal file
@ -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 "{-" "-}";
|
||||
136
Alisaie/AST.agda
Normal file
136
Alisaie/AST.agda
Normal file
@ -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)) #-}
|
||||
56
Alisaie/Abs.hs
Normal file
56
Alisaie/Abs.hs
Normal file
@ -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
Alisaie/Doc.txt
Normal file
105
Alisaie/Doc.txt
Normal file
@ -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).
|
||||
44
Alisaie/ErrM.hs
Normal file
44
Alisaie/ErrM.hs
Normal file
@ -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 = (<|>)
|
||||
56
Alisaie/IOLib.agda
Normal file
56
Alisaie/IOLib.agda
Normal file
@ -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
Alisaie/Lex.hs
Normal file
564
Alisaie/Lex.hs
Normal file
File diff suppressed because one or more lines are too long
270
Alisaie/Lex.x
Normal file
270
Alisaie/Lex.x
Normal file
@ -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
|
||||
]
|
||||
}
|
||||
22
Alisaie/Main.agda
Normal file
22
Alisaie/Main.agda
Normal file
@ -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
Alisaie/Par.hs
Normal file
1272
Alisaie/Par.hs
Normal file
File diff suppressed because one or more lines are too long
2041
Alisaie/Par.info
Normal file
2041
Alisaie/Par.info
Normal file
File diff suppressed because it is too large
Load Diff
182
Alisaie/Par.y
Normal file
182
Alisaie/Par.y
Normal file
@ -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
|
||||
|
||||
}
|
||||
|
||||
68
Alisaie/Parser.agda
Normal file
68
Alisaie/Parser.agda
Normal file
@ -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 #-}
|
||||
188
Alisaie/Print.hs
Normal file
188
Alisaie/Print.hs
Normal file
@ -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])
|
||||
64
Alisaie/Skel.hs
Normal file
64
Alisaie/Skel.hs
Normal file
@ -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
|
||||
77
Alisaie/Test.hs
Normal file
77
Alisaie/Test.hs
Normal file
@ -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
|
||||
|
||||
47
Makefile
Normal file
47
Makefile
Normal file
@ -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
|
||||
2
example.ali
Normal file
2
example.ali
Normal file
@ -0,0 +1,2 @@
|
||||
main : IO ()
|
||||
main = putStrLn "Hejsan"
|
||||
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
@ -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
|
||||
}
|
||||
40
flake.nix
Normal file
40
flake.nix
Normal file
@ -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