Compare commits

...

1 Commits

Author SHA1 Message Date
3cb85c7f42 toki: pona 2025-02-19 04:04:40 -06:00
4 changed files with 188 additions and 103 deletions

View File

@ -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<I: Display, W: Write>(
iterable: impl IntoIterator<Item = I>,
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(()),

View File

@ -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<Self, Self::Err> {
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(())?,
})
}

5
sample-code/hello.tp Normal file
View File

@ -0,0 +1,5 @@
// The main function
nasin wan () {
toki_linja("mi toki ale a!")
}

10
sample-code/pona.tp Normal file
View File

@ -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;