{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE PartialTypeSignatures #-} module Gyehoek.Syntax where import Data.Text (Text) import Data.List (List) import Language.SexpGrammar as Sexp hiding (List) import Language.SexpGrammar.Generic import GHC.Generics import Prelude hiding ((.), id) import Control.Category import Data.List.NonEmpty (NonEmpty ((:|))) import Gyehoek.Sexp qualified type Name = Text data Prim = PrimAdd | PrimSub | PrimMul | PrimDiv deriving (Show, Generic) data Lit = LitInt Int | LitNil | LitBool Bool deriving (Show, Generic) data Exp = ExpLet (NonEmpty (Name, Exp)) Exp | ExpApply Exp (List Exp) | ExpBegin (List Exp) | ExpLit Lit | ExpPrim Prim | ExpLambda (List Name) Exp | ExpVar Name deriving (Show, Generic) instance SexpIso Prim where sexpIso = match $ With (. sym "+") $ With (. sym "-") $ With (. sym "*") $ With (. sym "/") $ End instance SexpIso Lit where sexpIso = match $ With (. sexpIso) $ With (. sym "nil") $ With (. sexpIso) $ End where instance SexpIso Exp where sexpIso = match $ With (. Gyehoek.Sexp.let_ symbol sexpIso sexpIso) $ With (\app -> app . list (el sexpIso >>> rest sexpIso)) $ With (\bgn -> bgn . list (el (sym "begin") >>> rest sexpIso)) $ With (. sexpIso) $ With (. sexpIso) $ With (. lam) $ With (. symbol) $ End where lam = list ( el (sym "lambda") >>> el (sexpIso @(List Name)) >>> el sexpIso )