Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add with-unknown-type #71

Merged
merged 1 commit into from
May 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/unknown-type.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(nothing) : ∀α. (Maybe α)
(just #[unknown-type.kl:24.33-24.37]<here>) : (Maybe Syntax)
(just #<closure>) : ∀α. (Maybe (α → α))
(pair (just #<closure>) (nothing)) : ∀α. (Pair (Maybe (α → α)) (Maybe (α → α)))
28 changes: 28 additions & 0 deletions examples/unknown-type.kl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#lang "n-ary-app.kl"

(import (shift "n-ary-app.kl" 1))
(import (shift "quasiquote.kl" 1))
(import "pair-datatype.kl")

(define-macros
([gotta-be-maybe
(lambda (stx)
(syntax-case stx
[(list (_ e))
(pure (quasiquote/loc stx (with-unknown-type (A) (the (Maybe A) ,e))))]))]
[gotta-be-maybes
(lambda (stx)
(syntax-case stx
[(list (_ e1 e2))
(pure
(quasiquote/loc stx
(with-unknown-type (A)
(pair (the (Maybe A) ,e1)
(the (Maybe A) ,e2)))))]))]))

(example (gotta-be-maybe (nothing)))
(example (gotta-be-maybe (just 'here)))
(example (gotta-be-maybe (just (lambda (x) x))))


(example (gotta-be-maybes (just (lambda (x) x)) (nothing)))
11 changes: 11 additions & 0 deletions src/Expander.hs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ initializeKernel = do
traverse_ (uncurry addTypePrimitive) typePrims
traverse_ (uncurry addPatternPrimitive) patternPrims
traverse_ addDatatypePrimitive datatypePrims
addUniversalPrimitive "with-unknown-type" Prims.makeLocalType


where
typePrims :: [(Text, (SplitTypePtr -> Syntax -> Expand (), TypePatternPtr -> Syntax -> Expand ()))]
Expand Down Expand Up @@ -545,6 +547,13 @@ initializeKernel = do
bind b val
addToKernel name runtime b

addUniversalPrimitive :: Text -> (MacroDest -> Syntax -> Expand ()) -> Expand ()
addUniversalPrimitive name impl = do
let val = EPrimUniversalMacro impl
b <- freshBinding
bind b val
addToKernel name runtime b


-- TODO Make import spec language extensible and use bindings rather
-- than literals
Expand Down Expand Up @@ -982,6 +991,8 @@ expandOneForm prob stx
EPrimPatternMacro impl -> do
dest <- requirePatternCtx stx prob
impl dest stx
EPrimUniversalMacro impl ->
impl prob stx
EVarMacro var -> do
(t, dest) <- requireExpressionCtx stx prob
case syntaxE stx of
Expand Down
4 changes: 3 additions & 1 deletion src/Expander/Monad.hs
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,14 @@ newtype ExpansionEnv = ExpansionEnv (Map.Map Binding EValue)
deriving (Semigroup, Monoid)

data EValue
= EPrimExprMacro (Ty -> SplitCorePtr -> Syntax -> Expand ()) -- ^ For special forms
= EPrimExprMacro (Ty -> SplitCorePtr -> Syntax -> Expand ())
-- ^ For special forms
| EPrimTypeMacro (SplitTypePtr -> Syntax -> Expand ()) (TypePatternPtr -> Syntax -> Expand ())
-- ^ For type-level special forms - first as types, then as type patterns
| EPrimModuleMacro (Syntax -> Expand ())
| EPrimDeclMacro (DeclTreePtr -> DeclOutputScopesPtr -> Syntax -> Expand ())
| EPrimPatternMacro (Either (Ty, Ty, PatternPtr) (Ty, TypePatternPtr) -> Syntax -> Expand ())
| EPrimUniversalMacro (MacroDest -> Syntax -> Expand ())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a "universal" macro?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Universal in the sense that it works in any syntactic context, be it expression, type, decl, etc.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is its meaning in a pattern context? Looks like an error? And in a declaration context? What about a module context? (Not trying to be annoying, just trying to understand 😄)

| EVarMacro !Var -- ^ For bound variables (the Unique is the binding site of the var)
| ETypeVar !Natural -- ^ For bound type variables (user-written Skolem variables or in datatype definitions)
| EUserMacro !MacroVar -- ^ For user-written macros
Expand Down
26 changes: 26 additions & 0 deletions src/Expander/Primitives.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
Expand Down Expand Up @@ -49,6 +50,8 @@ module Expander.Primitives
, elsePattern
-- * Module primitives
, makeModule
-- * Anywhere primitives
, makeLocalType
-- * Local primitives
, prepareVar
) where
Expand Down Expand Up @@ -539,6 +542,29 @@ makeModule expandDeclForms stx =

pure ()

--------------
-- Anywhere --
--------------

makeLocalType :: MacroDest -> Syntax -> Expand ()
makeLocalType dest stx = do
Stx _ _ (_ :: Syntax, binder, body) <- mustHaveEntries stx
Stx _ _ theVar <- mustHaveEntries binder
(sc, n, b) <- varPrepHelper theVar
t <- TMetaVar <$> freshMeta

let tyImpl tdest tstx = do
_ <- mustBeIdent tstx
linkType tdest t
let patImpl _ tstx =
throwError $ NotValidType tstx

p <- currentPhase
addLocalBinding n b
bind b $ EPrimTypeMacro tyImpl patImpl

forkExpandSyntax dest (addScope p body sc)

--------------
-- Patterns --
--------------
Expand Down
2 changes: 2 additions & 0 deletions stdlib/n-ary-app.kl
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
(export #%module #%app
lambda define example define-macros quote meta
the -> Syntax Macro
with-unknown-type
if true false
error
let flet
Expand All @@ -108,4 +109,5 @@
free-identifier=? bound-identifier=? log make-introducer
Unit unit
ScopeAction flip add remove
Maybe just nothing
datatype case else)