Skip to content

Commit

Permalink
Add patch declaration.
Browse files Browse the repository at this point in the history
  • Loading branch information
typeswitch-dev committed Jan 29, 2025
1 parent b5ab51c commit eaeed94
Show file tree
Hide file tree
Showing 11 changed files with 799 additions and 600 deletions.
1,284 changes: 713 additions & 571 deletions bin/mirth0.c

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/def.mth
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,12 @@ data Def {
{ _ -> drop None }
}

def as-def-namespace? [ +Mirth Def -- +Mirth Maybe(Namespace) ] {
{ Alias -> ~target try-force! bind(as-def-namespace?) }
{ Word -> drop None }
{ _ -> as-namespace? }
}

def register [ +Mirth Def -- +Mirth ] {
dup qname-soft for(
dup undefined-soft? else(
Expand Down
38 changes: 30 additions & 8 deletions src/elab.mth
Original file line number Diff line number Diff line change
Expand Up @@ -1319,7 +1319,7 @@ def elab-match-exhaustive! [ +Mirth +Match -- +Mirth +Match ] {
def elab-module! [ Module +World +Mirth -- Module +World +Mirth ] {
dup start
elab-module-header!
over Namespace.Module Some with-defining-namespace (
over Namespace.Module PropLabel.DefiningNamespace prop Some with-defining-namespace (
elab-decls!
dup module-end? else(
"Unexpected token in module." emit-fatal-error!
Expand Down Expand Up @@ -1707,7 +1707,7 @@ def elab-data-tag! [ Data SyntaxDataTag +Mirth -- Data +Mirth ] {

def elab-data-decls! [ +World +Mirth Data Token -- +World +Mirth Data ] {
dup Some >error-token
over Tycon.Data Namespace.Tycon Some >defining-namespace
over Tycon.Data Namespace.Tycon PropLabel.DefiningNamespace prop Some >defining-namespace
LexicalState with-lexical-state (
while(dup arg-end? not, elab-decl!)
drop
Expand Down Expand Up @@ -1985,6 +1985,25 @@ def elab-inline! [ Token +World +Mirth -- Token +World +Mirth ] {
)
}

||| Elaborate a patch declaration. This is a way to add definitions in a
||| particular namespace.
|||
||| patch Namespace { Decl* }
def elab-patch! [ Token +World +Mirth -- Token +World +Mirth ] {
dup args-0
succ dup args-0
dup name/dname? else?("Expected a type constructor." emit-fatal-error!)
dip:dup PropLabel.DefiningNamespace prop2(
>name/dname
False >ignore-last-name
dup resolve-def-namespace
else?("Cannot compute patch namespace." emit-fatal-error!)
nip
) Some with-defining-namespace (
succ elab-decl-block!
)
}

||| Elaborate max-mirth-revision block. This will skip a
||| declaration block if mirth-revision is too high.
|||
Expand Down Expand Up @@ -2586,23 +2605,23 @@ def table-new! [ +Mirth head:Token name:Name state:PropState(QName) doc:Maybe(St
# FIELD #
#########

def resolve-def-namespace [ +Mirth Token name/dname:Name/DName -- +Mirth Maybe(Namespace) ] {
def resolve-def-namespace [ +Mirth Token name/dname:Name/DName ignore-last-name:Bool -- +Mirth Maybe(Namespace) ] {
>token
"namespace" >sort
True >ignore-last-name
False >report-ambiguous-as-warning
resolve-def(
filter-sort(dup rdip:exposed-tycon? >Bool)
filter-sort(dup rdip:as-def-namespace? >Bool)
filter-qualifiers
L0 filter-roots
)
bind(as-namespace?)
bind(as-def-namespace?)
}

def elab-qname-from-nonrelative-dname [ +Mirth Token DName arity:Int -- +Mirth QName ] {
dup Right >name/dname
dup root? else(drop "relative name not allowed" emit-fatal-error!)
last-name >name
True >ignore-last-name
dup resolve-def-namespace unwrap(panic-diagnostics!) >namespace
drop QName
}
Expand Down Expand Up @@ -2635,8 +2654,11 @@ def elab-def-qname [ +Mirth Token -- +Mirth QName ] {

||| The namespace for definitions by default.
def defining-namespace-or-error [ +Mirth Token -- +Mirth Namespace ] {
lexical-state defining-namespace
unwrap("error: no namespace for definition" emit-fatal-error!)
lexical-state defining-namespace(
unwrap("error: no namespace for definition" emit-fatal-error!)
compute Some
) lexical-state!
unwrap("error: couldn't compute namespace for definition" emit-fatal-error!)
nip
}

Expand Down
30 changes: 15 additions & 15 deletions src/macro.mth
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,22 @@ def import-statement-error! [ +Mirth Token -- +Mirth Token ] {
def prim-decl-macro! { MacroAction.Decl Macro.Prim Def.Macro register }
def prim-word-macro! { MacroAction.Arrow Macro.Prim Def.Macro register }


def +Mirth.init-macros! [ +Mirth -- +Mirth ] {
"module" [ module-statement-error! ] prim-decl-macro!
"import" [ import-statement-error! ] prim-decl-macro!
"alias" [ elab-alias! ] prim-decl-macro!
"inline" [ elab-inline! ] prim-decl-macro!
"def" [ elab-def! ] prim-decl-macro!
"def-missing" [ elab-def-missing! ] prim-decl-macro!
"def-type" [ elab-def-type! ] prim-decl-macro!
"external" [ elab-external! ] prim-decl-macro!
"buffer" [ elab-buffer! ] prim-decl-macro!
"table" [ elab-table! ] prim-decl-macro!
"field" [ elab-field! ] prim-decl-macro!
"data" [ elab-data! ] prim-decl-macro!
"struct" [ elab-struct! ] prim-decl-macro!
"embed-str" [ elab-embed-str! ] prim-decl-macro!
"module" [ module-statement-error! ] prim-decl-macro!
"import" [ import-statement-error! ] prim-decl-macro!
"patch" [ elab-patch! ] prim-decl-macro!
"alias" [ elab-alias! ] prim-decl-macro!
"inline" [ elab-inline! ] prim-decl-macro!
"def" [ elab-def! ] prim-decl-macro!
"def-missing" [ elab-def-missing! ] prim-decl-macro!
"def-type" [ elab-def-type! ] prim-decl-macro!
"external" [ elab-external! ] prim-decl-macro!
"buffer" [ elab-buffer! ] prim-decl-macro!
"table" [ elab-table! ] prim-decl-macro!
"field" [ elab-field! ] prim-decl-macro!
"data" [ elab-data! ] prim-decl-macro!
"struct" [ elab-struct! ] prim-decl-macro!
"embed-str" [ elab-embed-str! ] prim-decl-macro!
"max-mirth-revision" [ elab-max-mirth-revision! ] prim-decl-macro!
"min-mirth-revision" [ elab-min-mirth-revision! ] prim-decl-macro!

Expand Down
16 changes: 14 additions & 2 deletions src/mirth.mth
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def Builtin.Alloc! [ -- Builtin ] {

struct LexicalState {
error-token: Maybe(Token)
defining-namespace: Maybe(Namespace)
defining-namespace: Maybe(Prop(Namespace))
}

struct +Mirth {
Expand Down Expand Up @@ -229,7 +229,7 @@ def +Mirth.with-lexical-state(f) [ (*a +Mirth -- *b +Mirth) *a LexicalState +Mir
lexical-state(swap) dip(f) lexical-state!
}

def +Mirth.with-defining-namespace(f) [ (*a +Mirth -- *b +Mirth) *a Maybe(Namespace) +Mirth -- *b +Mirth ] {
def +Mirth.with-defining-namespace(f) [ (*a +Mirth -- *b +Mirth) *a Maybe(Prop(Namespace)) +Mirth -- *b +Mirth ] {
lexical-state:defining-namespace(swap)
dip(f) lexical-state:defining-namespace!
}
Expand All @@ -250,6 +250,7 @@ data PropState(b) {
}

data PropLabel {
DefiningNamespace
DataQName [ Data ]
DataParams [ Data ]
DataCType [ Data ]
Expand All @@ -274,6 +275,7 @@ data PropLabel {
MacroQName [ Macro ]
--
def trace; [ +Mirth +Str PropLabel -- +Mirth +Str ] {
{ DefiningNamespace -> "defining namespace"; }
{ DataQName -> "data qname at " ; rdip:head? location?; }
{ DataParams -> "data params at " ; rdip:head? location?; }
{ DataCType -> "data ctype at " ; rdip:head? location?; }
Expand Down Expand Up @@ -332,6 +334,16 @@ def(Prop.ready?, Prop(t) -- Maybe(t),
_ -> drop None
))

def Prop.compute [ Prop(t) +Mirth -- Maybe(t) Prop(t) +Mirth ] {
state (
dup >state match {
{ Ready -> Some }
{ Delay -> state> drop rotl with-lexical-state:run dup PropState.Ready >state Some }
{ Computing -> None }
} state>
)
}

def Prop.try-force! [ Mut(Prop(t)) +Mirth -- Maybe(t) +Mirth ] {
dup @ >prop
@prop state match {
Expand Down
2 changes: 1 addition & 1 deletion src/version.mth
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ module mirth.version
||| DD is the date, and nnn is some number that goes up within a single day. The only
||| thing that matters is that the overall number never goes down, only up.

def mirth-revision { 2025_01_28_001 }
def mirth-revision { 2025_01_29_001 }
17 changes: 17 additions & 0 deletions test/patch.mth
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module test.patch

import std.prelude
import std.world

struct Foo {
Int
}

patch Foo {
def bar [ Foo -- Int ] { /Foo }
}

def main {
100 Foo bar >Str print
}
# mirth-test # pout # 100
2 changes: 1 addition & 1 deletion tools/make-update.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash

make bin/mirth2.c
make bin/mirth3.c
diff -q bin/mirth0.c bin/mirth3.c || make update
make
Binary file modified tools/mirth-code/mirth-0.0.1.vsix
Binary file not shown.
2 changes: 1 addition & 1 deletion tools/mirth-code/syntaxes/mirth.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"keyword": {
"patterns": [{
"name": "keyword.control.mirth",
"match": "(?<![^\\s\\\"\\.:()\\[\\]\\{\\},])(module|import|inline|alias|data|struct|def|def-type|def-missing|external|table|field|embed-str|buffer|min-mirth-revision|max-mirth-revision)(?![^\\s\\\"\\.:()\\[\\]\\{\\},])"
"match": "(?<![^\\s\\\"\\.:()\\[\\]\\{\\},])(module|import|inline|alias|data|struct|def|def-type|def-missing|external|table|field|embed-str|buffer|min-mirth-revision|max-mirth-revision|patch)(?![^\\s\\\"\\.:()\\[\\]\\{\\},])"
}, {
"name": "keyword.operator.mirth",
"match": "(?<![^\\s\\\"\\.:()\\[\\]\\{\\},])(\\$|->|--|\\\\|=|_)(?![^\\s\\\"\\.:()\\[\\]\\{\\},])"
Expand Down
2 changes: 1 addition & 1 deletion tools/mirth-vim/syntax/mirth.vim
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ endif
syntax iskeyword 33,36-39,42-43,45,47-57,59-90,94-95,97-122,124,126

" reserved words -- these have special syntactic meaning
syntax keyword mirthReserved module import inline alias data struct def def-type def-missing external table field embed-str buffer max-mirth-revision min-mirth-revision --
syntax keyword mirthReserved module import inline alias data struct def def-type def-missing external table field embed-str buffer max-mirth-revision min-mirth-revision patch --
syntax keyword mirthSpecial -> \\

" words, numbers, and types
Expand Down

0 comments on commit eaeed94

Please sign in to comment.