From 3cb85c7f42982b7f37f499bbade48247de2598d1 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 19 Feb 2025 04:04:40 -0600 Subject: [PATCH] toki: pona --- compiler/cl-ast/src/ast_impl.rs | 160 ++++++++++++++++++++-------- compiler/cl-token/src/token_type.rs | 116 ++++++++++---------- sample-code/hello.tp | 5 + sample-code/pona.tp | 10 ++ 4 files changed, 188 insertions(+), 103 deletions(-) create mode 100644 sample-code/hello.tp create mode 100644 sample-code/pona.tp diff --git a/compiler/cl-ast/src/ast_impl.rs b/compiler/cl-ast/src/ast_impl.rs index 7ea808a..4a1caa1 100644 --- a/compiler/cl-ast/src/ast_impl.rs +++ b/compiler/cl-ast/src/ast_impl.rs @@ -9,8 +9,24 @@ mod display { use std::{ borrow::Borrow, fmt::{Display, Write}, + io::IsTerminal, }; + fn keyword(d: impl Display, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if std::io::stdout().is_terminal() { + write!(f, "\x1b[31m{d}\x1b[0m") + } else { + d.fmt(f) + } + } + fn ident(d: impl Display, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if std::io::stdout().is_terminal() { + write!(f, "\x1b[95m{d}\x1b[0m") + } else { + d.fmt(f) + } + } + fn separate( iterable: impl IntoIterator, sep: &'static str, @@ -30,7 +46,7 @@ mod display { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Mutability::Not => Ok(()), - Mutability::Mut => "mut ".fmt(f), + Mutability::Mut => keyword("ante ", f), } } } @@ -39,19 +55,28 @@ mod display { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Visibility::Private => Ok(()), - Visibility::Public => "pub ".fmt(f), + Visibility::Public => keyword("lukin ", f), } } } impl Display for Literal { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Literal::Bool(v) => v.fmt(f), - Literal::Char(v) => write!(f, "'{}'", v.escape_debug()), - Literal::Int(v) => v.fmt(f), - Literal::Float(v) => write!(f, "{:?}", f64::from_bits(*v)), - Literal::String(v) => write!(f, "\"{}\"", v.escape_debug()), + fn fmt(this: &Literal, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match this { + Literal::Bool(v) => v.fmt(f), + Literal::Char(v) => write!(f, "'{}'", v.escape_debug()), + Literal::Int(v) => v.fmt(f), + Literal::Float(v) => write!(f, "{:?}", f64::from_bits(*v)), + Literal::String(v) => write!(f, "\"{}\"", v.escape_debug()), + } + } + if std::io::stdout().is_terminal() { + write!(f, "\x1b[94m")?; + fmt(self, f)?; + write!(f, "\x1b[0m") + } else { + fmt(self, f) } } } @@ -77,7 +102,8 @@ mod display { impl Display for Meta { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { name, kind } = self; - write!(f, "{name}{kind}") + ident(name, f)?; + write!(f, "{kind}") } } @@ -119,9 +145,10 @@ mod display { impl Display for Alias { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { to, from } = self; + keyword("ijo", f)?; match from { - Some(from) => write!(f, "type {to} = {from};"), - None => write!(f, "type {to};"), + Some(from) => write!(f, " {to} = {from};"), + None => write!(f, " {to};"), } } } @@ -129,21 +156,28 @@ mod display { impl Display for Const { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { name, ty, init } = self; - write!(f, "const {name}: {ty} = {init}") + keyword("kiwen ", f)?; + ident(name, f)?; + write!(f, ": {ty} = {init}") } } impl Display for Static { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { mutable, name, ty, init } = self; - write!(f, "static {mutable}{name}: {ty} = {init}") + keyword("mute", f)?; + write!(f, " {mutable}")?; + ident(name, f)?; + write!(f, ": {ty} = {init}") } } impl Display for Module { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { name, kind } = self; - write!(f, "mod {name}{kind}") + keyword("selo ", f)?; + ident(name, f)?; + write!(f, "{kind}") } } @@ -172,7 +206,10 @@ mod display { }; debug_assert_eq!(bind.len(), types.len()); - write!(f, "fn {name} ")?; + keyword("nasin", f)?; + " ".fmt(f)?; + ident(name, f)?; + " ".fmt(f)?; { let mut f = f.delimit(INLINE_PARENS); for (idx, (arg, ty)) in bind.iter().zip(types.iter()).enumerate() { @@ -195,14 +232,17 @@ mod display { impl Display for Param { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { mutability, name } = self; - write!(f, "{mutability}{name}") + write!(f, "{mutability}")?; + ident(name, f) } } impl Display for Struct { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { name, kind } = self; - write!(f, "struct {name}{kind}") + keyword("lipu ", f)?; + ident(name, f)?; + write!(f, "{kind}") } } @@ -219,14 +259,18 @@ mod display { impl Display for StructMember { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { vis, name, ty } = self; - write!(f, "{vis}{name}: {ty}") + write!(f, "{vis}")?; + ident(name, f)?; + write!(f, ": {ty}") } } impl Display for Enum { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { name, kind } = self; - write!(f, "enum {name}{kind}") + keyword("kulupu ", f)?; + ident(name, f)?; + write!(f, "{kind}") } } @@ -242,7 +286,8 @@ mod display { impl Display for Variant { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { name, kind } = self; - write!(f, "{name}{kind}") + ident(name, f)?; + write!(f, "{kind}") } } @@ -260,7 +305,8 @@ mod display { impl Display for Impl { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { target, body } = self; - write!(f, "impl {target} ")?; + keyword("insa", f)?; + write!(f, " {target} ")?; write!(f.delimit(BRACES), "{body}") } } @@ -270,7 +316,9 @@ mod display { match self { ImplKind::Type(t) => t.fmt(f), ImplKind::Trait { impl_trait, for_type } => { - write!(f, "{impl_trait} for {for_type}") + write!(f, "{impl_trait} ")?; + keyword("ale", f)?; + write!(f, " {for_type}") } } } @@ -279,7 +327,8 @@ mod display { impl Display for Use { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { absolute, tree } = self; - f.write_str(if *absolute { "use ::" } else { "use " })?; + keyword("jo", f)?; + f.write_str(if *absolute { " ::" } else { " " })?; write!(f, "{tree};") } } @@ -289,8 +338,12 @@ mod display { match self { UseTree::Tree(tree) => separate(tree, ", ")(f.delimit(INLINE_BRACES)), UseTree::Path(path, rest) => write!(f, "{path}::{rest}"), - UseTree::Alias(path, name) => write!(f, "{path} as {name}"), - UseTree::Name(name) => write!(f, "{name}"), + UseTree::Alias(path, name) => { + write!(f, "{path} ")?; + keyword("sama ", f)?; + ident(name, f) + } + UseTree::Name(name) => ident(name, f), UseTree::Glob => write!(f, "*"), } } @@ -350,7 +403,8 @@ mod display { impl Display for TyFn { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { args, rety } = self; - write!(f, "fn {args}")?; + keyword("nasin", f)?; + write!(f, " {args}")?; match rety { Some(v) => write!(f, " -> {v}"), None => Ok(()), @@ -371,10 +425,10 @@ mod display { impl Display for PathPart { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - PathPart::SuperKw => "super".fmt(f), - PathPart::SelfKw => "self".fmt(f), - PathPart::SelfTy => "Self".fmt(f), - PathPart::Ident(id) => id.fmt(f), + PathPart::SuperKw => keyword("mama", f), + PathPart::SelfKw => keyword("mi", f), + PathPart::SelfTy => keyword("Mi", f), + PathPart::Ident(id) => ident(id, f), } } } @@ -439,7 +493,7 @@ mod display { ExprKind::For(v) => v.fmt(f), ExprKind::Break(v) => v.fmt(f), ExprKind::Return(v) => v.fmt(f), - ExprKind::Continue => "continue".fmt(f), + ExprKind::Continue => keyword("tama", f), } } } @@ -454,7 +508,10 @@ mod display { impl Display for Let { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { mutable, name, ty, init } = self; - write!(f, "let {mutable}{name}")?; + keyword("poki", f)?; + write!(f, " {mutable}")?; + ident(name, f)?; + if let Some(value) = ty { write!(f, ": {value}")?; } @@ -494,7 +551,8 @@ mod display { impl Display for Match { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { scrutinee, arms } = self; - write!(f, "match {scrutinee} ")?; + keyword("seme", f)?; + write!(f, " {scrutinee} ")?; separate(arms, ",\n")(f.delimit(BRACES)) } } @@ -589,7 +647,7 @@ mod display { impl Display for UnaryKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - UnaryKind::Loop => "loop ", + UnaryKind::Loop => return keyword("awen ", f), UnaryKind::Deref => "*", UnaryKind::Neg => "-", UnaryKind::Not => "!", @@ -603,7 +661,9 @@ mod display { impl Display for Cast { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { head, ty } = self; - write!(f, "{head} as {ty}") + write!(f, "{head} ")?; + keyword("sama", f)?; + write!(f, " {ty}") } } @@ -617,9 +677,12 @@ mod display { impl Display for MemberKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - MemberKind::Call(name, args) => write!(f, "{name}{args}"), - MemberKind::Struct(name) => write!(f, "{name}"), - MemberKind::Tuple(name) => write!(f, "{name}"), + MemberKind::Call(name, args) => { + ident(name, f)?; + separate(&args.exprs, ", ")(f.delimit(INLINE_PARENS)) + } + MemberKind::Struct(name) => ident(name, f), + MemberKind::Tuple(name) => ident(name, f), } } } @@ -643,7 +706,7 @@ mod display { impl Display for Fielder { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { name, init } = self; - write!(f, "{name}")?; + ident(name, f)?; if let Some(init) = init { write!(f, ": {init}")?; } @@ -703,28 +766,35 @@ mod display { impl Display for While { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { cond, pass, fail } = self; - write!(f, "while {cond} {pass}{fail}") + write!(f, "lawa {cond} {pass}{fail}") } } impl Display for If { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { cond, pass, fail } = self; - write!(f, "if {cond} {pass}{fail}") + keyword("tan", f)?; + write!(f, " {cond} {pass}{fail}") } } impl Display for For { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Self { bind, cond, pass, fail } = self; - write!(f, "for {bind} in {cond} {pass}{fail}") + keyword("ale", f)?; + write!(f, " {bind} ")?; + keyword("lon", f)?; + write!(f, " {cond} {pass}{fail}") } } impl Display for Else { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self.body { - Some(body) => write!(f, " else {body}"), + Some(body) => { + keyword(" taso", f)?; + write!(f, " {body}") + } _ => Ok(()), } } @@ -732,7 +802,7 @@ mod display { impl Display for Break { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "break")?; + keyword("pana", f)?; match &self.body { Some(body) => write!(f, " {body}"), _ => Ok(()), @@ -742,7 +812,7 @@ mod display { impl Display for Return { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "return")?; + keyword("pini", f)?; match &self.body { Some(body) => write!(f, " {body}"), _ => Ok(()), diff --git a/compiler/cl-token/src/token_type.rs b/compiler/cl-token/src/token_type.rs index c874e86..1701331 100644 --- a/compiler/cl-token/src/token_type.rs +++ b/compiler/cl-token/src/token_type.rs @@ -107,35 +107,35 @@ impl Display for TokenKind { TokenKind::Literal => "literal".fmt(f), TokenKind::Identifier => "identifier".fmt(f), - TokenKind::As => "as".fmt(f), - TokenKind::Break => "break".fmt(f), - TokenKind::Cl => "cl".fmt(f), - TokenKind::Const => "const".fmt(f), - TokenKind::Continue => "continue".fmt(f), - TokenKind::Else => "else".fmt(f), - TokenKind::Enum => "enum".fmt(f), - TokenKind::False => "false".fmt(f), - TokenKind::Fn => "fn".fmt(f), - TokenKind::For => "for".fmt(f), - TokenKind::If => "if".fmt(f), - TokenKind::Impl => "impl".fmt(f), - TokenKind::In => "in".fmt(f), - TokenKind::Let => "let".fmt(f), - TokenKind::Loop => "loop".fmt(f), - TokenKind::Match => "match".fmt(f), - TokenKind::Mod => "mod".fmt(f), - TokenKind::Mut => "mut".fmt(f), - TokenKind::Pub => "pub".fmt(f), - TokenKind::Return => "return".fmt(f), - TokenKind::SelfKw => "self".fmt(f), - TokenKind::SelfTy => "Self".fmt(f), - TokenKind::Static => "static".fmt(f), - TokenKind::Struct => "struct".fmt(f), - TokenKind::Super => "super".fmt(f), - TokenKind::True => "true".fmt(f), - TokenKind::Type => "type".fmt(f), - TokenKind::Use => "use".fmt(f), - TokenKind::While => "while".fmt(f), + TokenKind::As => "sama".fmt(f), + TokenKind::Break => "pana".fmt(f), + TokenKind::Cl => "la".fmt(f), + TokenKind::Const => "kiwen".fmt(f), + TokenKind::Continue => "tawa".fmt(f), + TokenKind::Else => "taso".fmt(f), + TokenKind::Enum => "kulupu".fmt(f), + TokenKind::False => "ike".fmt(f), + TokenKind::Fn => "nasin".fmt(f), + TokenKind::For => "ale".fmt(f), + TokenKind::If => "tan".fmt(f), + TokenKind::Impl => "insa".fmt(f), + TokenKind::In => "lon".fmt(f), + TokenKind::Let => "poki".fmt(f), + TokenKind::Loop => "awen".fmt(f), + TokenKind::Match => "seme".fmt(f), + TokenKind::Mod => "selo".fmt(f), + TokenKind::Mut => "ante".fmt(f), + TokenKind::Pub => "lukin".fmt(f), + TokenKind::Return => "pini".fmt(f), + TokenKind::SelfKw => "mi".fmt(f), + TokenKind::SelfTy => "Mi".fmt(f), + TokenKind::Static => "mute".fmt(f), + TokenKind::Struct => "lipu".fmt(f), + TokenKind::Super => "mama".fmt(f), + TokenKind::True => "pona".fmt(f), + TokenKind::Type => "ijo".fmt(f), + TokenKind::Use => "jo".fmt(f), + TokenKind::While => "lawa".fmt(f), TokenKind::LCurly => "{".fmt(f), TokenKind::RCurly => "}".fmt(f), @@ -200,35 +200,35 @@ impl FromStr for TokenKind { /// Parses a string s to return a Keyword fn from_str(s: &str) -> Result { Ok(match s { - "as" => Self::As, - "break" => Self::Break, - "cl" => Self::Cl, - "const" => Self::Const, - "continue" => Self::Continue, - "else" => Self::Else, - "enum" => Self::Enum, - "false" => Self::False, - "fn" => Self::Fn, - "for" => Self::For, - "if" => Self::If, - "impl" => Self::Impl, - "in" => Self::In, - "let" => Self::Let, - "loop" => Self::Loop, - "match" => Self::Match, - "mod" => Self::Mod, - "mut" => Self::Mut, - "pub" => Self::Pub, - "return" => Self::Return, - "self" => Self::SelfKw, - "Self" => Self::SelfTy, - "static" => Self::Static, - "struct" => Self::Struct, - "super" => Self::Super, - "true" => Self::True, - "type" => Self::Type, - "use" => Self::Use, - "while" => Self::While, + "as" | "sama" => Self::As, + "break" | "pana" => Self::Break, + "cl" | "la" => Self::Cl, + "const" | "kiwen" => Self::Const, + "continue" | "tawa" => Self::Continue, + "else" | "taso" => Self::Else, + "enum" | "kulupu" => Self::Enum, + "false" | "ike" => Self::False, + "fn" | "nasin" => Self::Fn, + "for" | "ale" => Self::For, + "if" | "tan" => Self::If, + "impl" | "insa" => Self::Impl, + "in" | "lon" => Self::In, + "let" | "poki" => Self::Let, + "loop" | "awen" => Self::Loop, + "match" | "seme" => Self::Match, + "mod" | "selo" => Self::Mod, + "mut" | "ante" => Self::Mut, + "pub" | "lukin" => Self::Pub, + "return" | "pini" => Self::Return, + "self" | "mi" => Self::SelfKw, + "Self" | "Mi" => Self::SelfTy, + "static" | "mute" => Self::Static, + "struct" | "lipu" => Self::Struct, + "super" | "mama" => Self::Super, + "true" | "pona" => Self::True, + "type" | "ijo" => Self::Type, + "use" | "jo" => Self::Use, + "while" | "lawa" => Self::While, _ => Err(())?, }) } diff --git a/sample-code/hello.tp b/sample-code/hello.tp new file mode 100644 index 0000000..2bfeba4 --- /dev/null +++ b/sample-code/hello.tp @@ -0,0 +1,5 @@ + +// The main function +nasin wan () { + toki_linja("mi toki ale a!") +} diff --git a/sample-code/pona.tp b/sample-code/pona.tp new file mode 100644 index 0000000..e86d40c --- /dev/null +++ b/sample-code/pona.tp @@ -0,0 +1,10 @@ +//! toki! + +nasin toki_pona(nimi: linja) -> linja { + seme nimi { + "a" => "PARTICLE: Emphasis or emotion", + _ => "", + } +} + +kiwen main: nasin(Linja) -> Linja = toki_pona;