Compare commits

..

1 commit

Author SHA1 Message Date
Erin c4fbc7a0c1 Syntactic changes 2023-09-15 23:22:45 +02:00
12 changed files with 71 additions and 92 deletions

View file

@ -2,9 +2,6 @@ var std = include "std";
var print = std.print;
func main(){
// Arrays do exist only tuples packed into a single var
// zero indexed
var arr = (123, 456, 789);
// Print 456
print(arr.1);
var arr = [123, 456, 789];
print(arr[1]);
}

View file

@ -1,2 +1 @@
// there must only be one main and it ***MUST*** exist
func main(){}

View file

@ -1,18 +1,10 @@
func main() {
var abc = 0;
// an asm block may use variables outside of the asm scope
asm {
li r1, abc
jmp r0, start
start:
jmp r0, start
}
// This is not really a requirement
opcode {
01
}
// Exit
var exit_status = 0;
asm {
li r255, exit_status
tx
}
}

View file

@ -1,6 +1,3 @@
// The only thing included here is the ability to pull in other functions
// This is not a * include
var std = include "std";
func main(){}

View file

@ -1,15 +1,11 @@
func main(){
var i = 0;
// The only loop is `loop` and it does not do any form of count up and break
loop {
match i {
// break will break out of `one` loop
10 -> break;
}
// Increment by one
i = i + 1;
}
// This is functionally identical to a HCF
loop {}
}

View file

@ -5,6 +5,5 @@ func main() {
match 2 {
1 -> { print("One") }
2 -> { print("Two") }
// If there is not a matching case continue
}
}

View file

@ -1,10 +0,0 @@
// This string ***MUST*** never be edited
const b_string = "XYZ";
func main() {
var a_string = "ABC";
// strings may be added together
var fmt = a_string + " length " + a_string.len;
// print may only take one argument
print(fmt);
}

View file

@ -1,5 +1,4 @@
func random_u64(){
// TODO: randomness
var value = 0;
return value;
return 3;
}

View file

@ -1,7 +1,5 @@
var log = include "log";
// print accepts all types in value
func print(value) {
// TODO: define an api for output
}

View file

@ -26,20 +26,32 @@ pub enum Expr<'a> {
Call(ExprRef<'a>, ExprList<'a>),
Binary(Spanned<BinaryOperator>, ExprRef<'a>, ExprRef<'a>),
Unary(Spanned<UnaryOperator>, ExprRef<'a>),
BindLocal(Spanned<Pattern>, ExprRef<'a>, Option<ExprList<'a>>),
BindIn(
Spanned<Pattern>,
ExprRef<'a>,
ExprList<'a>,
Option<ExprList<'a>>,
),
Def(DefKind, Spanned<Ident>, Option<Spanned<Type>>, ExprRef<'a>),
Set(ExprRef<'a>, ExprRef<'a>),
Match(ExprRef<'a>, &'a [(Spanned<Pattern>, SpanExpr<'a>)]),
Func(&'a [(Spanned<Pattern>, Spanned<Type>)], Spanned<Type>, ExprRef<'a>),
Switch(
ExprRef<'a>,
&'a [(Spanned<Pattern>, SpanExpr<'a>)],
Option<ExprRef<'a>>,
),
Loop(ExprList<'a>),
Func(
&'a [(Spanned<Ident>, Spanned<Type>)],
Spanned<Type>,
ExprRef<'a>,
),
Block(ExprList<'a>),
Break(Option<ExprRef<'a>>),
Return(Option<ExprRef<'a>>),
Continue,
Unit,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DefKind {
Const,
Var,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Type {
Ident(Ident),
@ -50,7 +62,6 @@ pub enum Type {
pub enum Pattern {
Ident(Ident),
Literal(Literal),
None,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]

View file

@ -1,8 +1,8 @@
use super::ast::Type;
use super::ast::DefKind;
use {
super::{
ast::{BinaryOperator, Expr, Literal, Pattern, SpanExpr, Spanned, UnaryOperator},
ast::{BinaryOperator, Expr, Literal, Pattern, SpanExpr, Spanned, Type, UnaryOperator},
token::Token,
},
crate::utils::Pipe,
@ -35,13 +35,6 @@ where
Token::String(a) => Literal::String(a)
};
let pattern = select! {
Token::Ident(id) => Pattern::Ident(id),
Token::Underscore => Pattern::None,
}
.or(literal.map(Pattern::Literal))
.map_with_span(Spanned::new);
let type_ = just([Token::LeftParen, Token::RightParen])
.to(Type::Unit)
.or(ident.map(Type::Ident))
@ -56,8 +49,9 @@ where
let func = just(Token::Func)
.ignore_then(
pattern
.then_ignore(just(Token::Colon))
ident
.map_with_span(Spanned::new)
.then_ignore(just(Token::RArrow))
.then(type_)
.separated_by(just(Token::Comma))
.allow_trailing()
@ -158,26 +152,13 @@ where
},
);
let bind = {
let start = pattern.then_ignore(just(Token::Colon)).then(expr.clone()); // <pat> := <expr>
let else_ = just(Token::Else).ignore_then(block.clone()).or_not(); // else {…}
// <pat> := <expr> [else {…}]
let local = start.clone().then(else_.clone()).map_with_state(
|((pat, expr), else_), _, state| {
Expr::BindLocal(pat, &*state.arena.alloc(expr), else_)
},
);
// <pat> := <expr> {…} else {…}
let in_ = start.then(block.clone()).then(else_).map_with_state(
|(((pat, expr), block), else_), _, state| {
Expr::BindIn(pat, &*state.arena.alloc(expr), block, else_)
},
);
in_.or(local)
};
// (const/var) <ident> [:<type>] = <expr>
let def = equivmap!(Token, DefKind, [Var, Const])
.then(ident.map_with_span(Spanned::new))
.then(just(Token::Colon).ignore_then(type_).or_not())
.then_ignore(just(Token::Equ))
.then(expr.clone().pipe(arena_box))
.map(|(((kind, ident), type_), expr)| Expr::Def(kind, ident, type_, expr));
// <atom> ← <expr>
let set = atom
@ -188,25 +169,44 @@ where
Expr::Set(state.arena.alloc(place), state.arena.alloc(expr))
});
// <expr>.match { <pat> → <expr>, … }
let match_ = atom
// <atom>.switch { <pat> → <expr>, … }
let switch = atom
.clone()
.then_ignore(just([Token::Dot, Token::Match]))
.then_ignore(just([Token::Dot, Token::Switch]))
.then(
pattern
ident
.map(Pattern::Ident)
.or(literal.map(Pattern::Literal))
.map_with_span(Spanned::new)
.then_ignore(just(Token::RArrow))
.then(expr)
.then(expr.clone())
.separated_by(just(Token::Comma))
.allow_trailing()
.pipe(arena_collect)
.then(
just(Token::Else)
.ignore_then(just(Token::RArrow))
.ignore_then(expr.clone().pipe(arena_box))
.or_not(),
)
.delimited_by(just(Token::LeftCurly), just(Token::RightCurly)),
)
.map_with_state(|(expr, branches), _, state| {
Expr::Match(state.arena.alloc(expr), branches)
.map_with_state(|(expr, (branches, else_)), _, state| {
Expr::Switch(state.arena.alloc(expr), branches, else_)
});
bind.or(set)
.or(match_)
let loop_ = just(Token::Loop).ignore_then(block.clone()).map(Expr::Loop);
let brk_ret = just(Token::Break)
.to(Expr::Break as fn(_) -> _)
.or(just(Token::Ret).to(Expr::Return as fn(_) -> _))
.then(expr.pipe(arena_box).or_not())
.map(|(variant, expr)| variant(expr));
def.or(set)
.or(switch)
.or(loop_)
.or(brk_ret)
.or(just(Token::Continue).to(Expr::Continue))
.or(block.map(Expr::Block))
.map_with_span(Spanned::new)
.or(binary)

View file

@ -55,14 +55,15 @@ pub enum Token {
#[token("") ] //___,
#[token(">=")] GtEqu,
#[token("match")] Match,
#[token("switch")] Switch,
#[token("else")] Else,
#[token("loop")] Loop,
#[token("continue")] Continue,
#[token("break")] Break,
#[token("ret")] Ret,
#[token("const")] Const,
#[token("var")] Var,
#[token("func")] Func,
// Modules aren't real here ondra just variables with imported functions
#[token("module")] Module,
#[regex(
r"\p{XID_Start}\p{XID_Continue}*",