Skip to content

Commit

Permalink
Syntax: overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Nov 20, 2024
1 parent f8b1a82 commit 2802a1b
Show file tree
Hide file tree
Showing 53 changed files with 683 additions and 736 deletions.
24 changes: 11 additions & 13 deletions data/features.no
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ use std::fmt::Show
// sum type
type Vec2(x: Float, y: Float)

// inherent impl
impl Vec2 {
fn size(self): Float {
self.x ^ 2. + self.y ^ 2.
}
// function
fn size(vec: Vec2): Float {
vec.x ^ 2. + vec.y ^ 2.
}

// impl
impl Show for Vec2 {
fn show(self): String {
impl Show<Vec2> {
show = fn(self): String {
"(" + self.x + ", " + self.y + ")"
}
}
Expand Down Expand Up @@ -126,20 +124,20 @@ fn main() {
let r = Vec2::show
}

trait Show<I> {
trait Show {
// actual type is fn<T: Show<T>>(a: T): String
show = fn(a: I): String
show = fn(self): String
}

trait Debug<I> {
debug = fn(a: I): String
trait Debug {
debug = fn(self): String
}

impl Show<String> {
impl Show for String {
show = id
}

impl <T: Debug<T>> Show<T> {
impl <T: Debug<T>> Show for T {
show = fn(a: T): String {
// sugar for debug(a)
a.debug()
Expand Down
13 changes: 6 additions & 7 deletions data/nois3.no
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,29 @@ type User(name Name, age Int)
type Name = String

trait Eq {
fn eq(self, other Self) Bool
eq = fn(self, other Self) Bool
}

trait Ord<Self: Eq> {
fn cmp(self, other Self) Ordering
cmp = fn(self, other Self) Ordering

fn lt(self, other Self) Bool {
lt = fn(self, other Self) Bool {
self.cmp(other) == Less
}
}

trait Show {
fn show(self) String
show = fn(self) String
}

impl Show for Option<User> {
fn show(self) String {
show = fn(self) String {
"Maybe user!!!"
}
}

impl <T: Eq + Ord> Show for Option<T> {
fn show(self) String {
show = fn(self) String {
match self {
Some(value) { value.show() }
None() { "None" }
Expand All @@ -64,7 +64,6 @@ impl <T: Eq + Ord> Show for Option<T> {
}

fn main() {

let u = User("Jack", 13)
let u = User(name = "Jack", age = 13)

Expand Down
1 change: 0 additions & 1 deletion ideas.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
- Infer type parameters bounds in inherent impl def https://rust-lang.github.io/rfcs/2089-implied-bounds.html
- Block is a valid expression
- std::test
- noisdoc
Expand Down
48 changes: 25 additions & 23 deletions nois.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,15 @@ statement ::= var-def | fn-def | trait-def | impl-def | type-def | r
;
var-def ::= PUB-KEYWORD? LET-KEYWORD pattern type-annot? (EQUALS expr)?
;
fn-def ::= PUB-KEYWORD? FN-KEYWORD NAME generics? params type-annot? block?
trait-def ::= PUB-KEYWORD? TRAIT-KEYWORD NAME type-params? trait-block
;
generics ::= O-ANGLE (generic (COMMA generic)* COMMA?)? C-ANGLE
trait-block ::= O-BRACE trait-statement* C-BRACE
;
generic ::= NAME (COLON type-bounds)?
trait-statement ::= NAME EQUALS expr
;
params ::= O-PAREN (param (COMMA param)*)? COMMA? C-PAREN
impl-def ::= IMPL-KEYWORD type-params? FOR-KEYWORD identifier trait-block
;
param ::= pattern type-annot?
;
trait-def ::= PUB-KEYWORD? TRAIT-KEYWORD NAME generics? block
;
impl-def ::= IMPL-KEYWORD generics? identifier impl-for? block
;
impl-for ::= FOR-KEYWORD identifier
;
type-def ::= PUB-KEYWORD? TYPE-KEYWORD NAME generics? (variant-list | variant-params)?
type-def ::= PUB-KEYWORD? TYPE-KEYWORD NAME type-params? (variant-list | variant-params)?
;
variant-params ::= O-PAREN (field-def (COMMA field-def)*)? COMMA? C-PAREN
;
Expand All @@ -44,13 +36,13 @@ statement ::= var-def | fn-def | trait-def | impl-def | type-def | r
;
sub-expr ::= operand postfix-op*
;
operand ::= while-expr
operand ::= fn-def
| while-expr
| for-expr
| match-expr
| closure-expr
| list-expr
| string
| CHAR
| char
| number
| bool
| identifier
Expand Down Expand Up @@ -96,20 +88,28 @@ type ::= identifier | fn-type | hole
;
type-bounds ::= identifier (PLUS identifier)*
;
fn-type ::= generics? fn-type-params type-annot
fn-type ::= FN-KEYWORD type-params? fn-type-params type-annot
;
fn-type-params ::= PIPE (type (COMMA type)* COMMA?)? PIPE
fn-type-params ::= O-BRACE (param-type (COMMA param-type)* COMMA?)? C-BRACE
;
block ::= O-BRACE statement* C-BRACE
;
closure-expr ::= closure-params type-annot? (block | statement)
param-type ::= NAME COLON type
;
closure-params ::= PIPE (param (COMMA param)*)? COMMA? PIPE
block ::= O-BRACE statement* C-BRACE
;
list-expr ::= O-BRACKET (expr (COMMA expr)*)? COMMA? C-BRACKET
;
type-annot ::= COLON type
;
fn-def ::= FN-KEYWORD type-params params type-annot? block?
;
params ::= O-PAREN (param (COMMA param)*)? COMMA? C-PAREN
;
param ::= pattern type-annot?
;
type-params ::= O-ANGLE (type-param (COMMA type-param)* COMMA?)? C-ANGLE
;
type-param ::= NAME (COLON type-bounds)?
;
while-expr ::= WHILE-KEYWORD expr block
;
for-expr ::= FOR-KEYWORD pattern IN-KEYWORD expr block
Expand All @@ -128,7 +128,7 @@ pattern ::= pattern-bind? pattern-expr
;
pattern-bind ::= NAME AT
;
pattern-expr ::= string | CHAR | number | bool | hole | NAME | con-pattern | list-pattern
pattern-expr ::= string | char | number | bool | hole | NAME | con-pattern | list-pattern
;
con-pattern ::= identifier con-pattern-params
;
Expand All @@ -142,6 +142,8 @@ pattern ::= pattern-bind? pattern-expr
;
number ::= MINUS? (INT | FLOAT)
;
char ::= QUOTE CHAR QUOTE
;
string ::= D-QUOTE string-part* D-QUOTE
;
string-part ::= STRING | O-BRACE expr C-BRACE
Expand Down
4 changes: 2 additions & 2 deletions src/ast/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
buildStatement,
buildUseExpr
} from './statement'
import { FnType, Generic, Type, buildType } from './type'
import { FnType, TypeParam, Type, buildType } from './type'
import { FieldDef, TypeDef, Variant } from './type-def'

export type AstNode =
Expand All @@ -66,7 +66,7 @@ export type AstNode =
| Block
| Param
| FnType
| Generic
| TypeParam
| MatchClause
| Pattern
| ConPattern
Expand Down
54 changes: 28 additions & 26 deletions src/ast/operand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { assert } from '../util/todo'
import { Expr, buildExpr } from './expr'
import { BaseAstNode, Param, buildParam } from './index'
import { MatchExpr, Pattern, buildMatchExpr, buildNumber, buildPattern } from './match'
import { Block, buildBlock, buildStatement } from './statement'
import { Type, buildType } from './type'
import { Block, TraitDef, buildBlock } from './statement'
import { Type, TypeParam, buildType, buildTypeParam } from './type'

export type Operand =
| FnDef
| WhileExpr
| ForExpr
| MatchExpr
| ClosureExpr
| ListExpr
| StringLiteral
| StringInterpolated
Expand All @@ -24,17 +24,40 @@ export type Operand =
| Identifier
| Block

export type FnDef = BaseAstNode & {
kind: 'fn-def'
typeParams: TypeParam[]
params: Param[]
block?: Block
returnType?: Type
static?: boolean
trait?: TraitDef
}

export const buildFnDef = (node: ParseNode, ctx: Context): FnDef => {
const nodes = filterNonAstNodes(node)
let idx = 0
// skip fn-keyword
idx++
const typeParams =
nodes.at(idx)?.kind === 'type-params' ? filterNonAstNodes(nodes[idx++]).map(n => buildTypeParam(n, ctx)) : []
const params = nodes.at(idx)?.kind === 'params' ? filterNonAstNodes(nodes[idx++]).map(n => buildParam(n, ctx)) : []
const returnType = nodes.at(idx)?.kind === 'type-annot' ? buildType(nodes[idx++], ctx) : undefined
const block = nodes.at(idx)?.kind === 'block' ? buildBlock(nodes[idx++], ctx) : undefined
return { kind: 'fn-def', parseNode: node, typeParams, params, block, returnType }
}

export const buildOperand = (node: ParseNode, ctx: Context): Operand => {
const n = filterNonAstNodes(node)[0]
switch (n.kind) {
case 'fn-def':
return buildFnDef(n, ctx)
case 'while-expr':
return buildWhileExpr(n, ctx)
case 'for-expr':
return buildForExpr(n, ctx)
case 'match-expr':
return buildMatchExpr(n, ctx)
case 'closure-expr':
return buildClosureExpr(n, ctx)
case 'list-expr':
return buildListExpr(n, ctx)
case 'string':
Expand Down Expand Up @@ -94,27 +117,6 @@ export const buildForExpr = (node: ParseNode, ctx: Context): ForExpr => {
return { kind: 'for-expr', parseNode: node, pattern, expr, block }
}

export type ClosureExpr = BaseAstNode & {
kind: 'closure-expr'
params: Param[]
block: Block
returnType?: Type
}

export const buildClosureExpr = (node: ParseNode, ctx: Context): ClosureExpr => {
const nodes = filterNonAstNodes(node)
let idx = 0
const params = filterNonAstNodes(nodes[idx++])
.filter(n => n.kind === 'param')
.map(n => buildParam(n, ctx))
const returnType = nodes.at(idx)?.kind === 'type-annot' ? buildType(nodes[idx++], ctx) : undefined
const block: Block =
nodes[idx].kind === 'block'
? buildBlock(nodes[idx++], ctx)
: { kind: 'block', parseNode: nodes[idx], statements: [buildStatement(nodes[idx++], ctx)] }
return { kind: 'closure-expr', parseNode: node, params, block, returnType }
}

export type ListExpr = BaseAstNode & {
kind: 'list-expr'
exprs: Expr[]
Expand Down
Loading

0 comments on commit 2802a1b

Please sign in to comment.