diff --git a/src/ast/lit.rs b/src/ast/lit.rs index 59cef61..1af89cf 100644 --- a/src/ast/lit.rs +++ b/src/ast/lit.rs @@ -1,5 +1,6 @@ use std::fmt; +use crate::builtin::Builtin; use crate::span::{HasSpan, Span}; use super::basic::{Ident, Space}; @@ -127,6 +128,10 @@ pub enum Lit { /// - `false` Bool(bool, Span), + /// - `'get` + /// - `'destructure` + Builtin(Builtin, Span), + /// See [`NumLit`]. Num(NumLit), @@ -142,6 +147,7 @@ impl fmt::Debug for Lit { match self { Self::Nil(_) => write!(f, "l#nil"), Self::Bool(b, _) => write!(f, "l#{b:?}"), + Self::Builtin(b, _) => write!(f, "l#{b:?}"), Self::Num(n) => write!(f, "l#{n:?}"), Self::String(s) => write!(f, "l#{s:?}"), Self::Table(t) => { @@ -157,6 +163,7 @@ impl HasSpan for Lit { match self { Lit::Nil(span) => *span, Lit::Bool(_, span) => *span, + Lit::Builtin(_, span) => *span, Lit::Num(n) => n.span(), Lit::String(s) => s.span(), Lit::Table(t) => t.span(), diff --git a/src/builtin.rs b/src/builtin.rs index 117061d..f0e504d 100644 --- a/src/builtin.rs +++ b/src/builtin.rs @@ -1,21 +1,31 @@ -// Possible future built-ins -// -// #get - Get table's value at a key/path -// #set - Set table's value at a key/path -// #raw - Interpret values literally (either recursively or only one layer) -// #path - Construct a path from a table -// #scope - Execute a command in a new sub-scope -// #loop - Repeat a command infinitely -// #break - Break out of an infinite loop (with a value?) -// #if - Conditionally execute one of two commands -// #print - Print a string to stdout -// #input - Read a line from stdin -// #read - Load the contents of a file as string -// #write - Store a string into a file -// Arithmetic: #add #sub #neg #shiftr #shiftl -// Booleans: #and #or #not #xor #andb #orb #notb #xorb -// Comparisons: #eq #neq #lt #le #gt #ge +use std::fmt; /// Built-in operations -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum Builtin {} +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub enum Builtin { + Get, + Set, + GetRaw, + SetRaw, + GetMeta, + SetMeta, + Scope, + Arg, + Destructure, +} + +impl fmt::Debug for Builtin { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Get => write!(f, "'get"), + Self::Set => write!(f, "'set"), + Self::GetRaw => write!(f, "'getraw"), + Self::SetRaw => write!(f, "'setraw"), + Self::GetMeta => write!(f, "'getmeta"), + Self::SetMeta => write!(f, "'setmeta"), + Self::Scope => write!(f, "'scope"), + Self::Arg => write!(f, "'arg"), + Self::Destructure => write!(f, "'destructure"), + } + } +} diff --git a/src/parser/lit.rs b/src/parser/lit.rs index 29b7ab5..afd9251 100644 --- a/src/parser/lit.rs +++ b/src/parser/lit.rs @@ -3,9 +3,24 @@ use chumsky::prelude::*; use crate::ast::{Expr, Lit, NumLit, NumLitStr, StringLit, TableLit, TableLitElem}; +use crate::builtin::Builtin; use super::basic::{ident, space, Error}; +fn builtin_lit() -> impl Parser { + just('\'').ignore_then(choice(( + text::keyword("get").to(Builtin::Get), + text::keyword("set").to(Builtin::Set), + text::keyword("getraw").to(Builtin::GetRaw), + text::keyword("setraw").to(Builtin::SetRaw), + text::keyword("getmeta").to(Builtin::GetMeta), + text::keyword("setmeta").to(Builtin::SetMeta), + text::keyword("scope").to(Builtin::Scope), + text::keyword("arg").to(Builtin::Arg), + text::keyword("destructure").to(Builtin::Destructure), + ))) +} + fn num_lit_str_radix(radix: u32) -> impl Parser + Clone { // Minimum amount of digits required to represent i64::MAX. The rest of this // code assumes that any value that can be represented using this amount of @@ -119,9 +134,15 @@ pub fn lit( let nil = text::keyword("nil").map_with_span(|_, span| Lit::Nil(span)); let r#true = text::keyword("true").map_with_span(|_, span| Lit::Bool(true, span)); let r#false = text::keyword("false").map_with_span(|_, span| Lit::Bool(false, span)); + let builtin = builtin_lit().map_with_span(Lit::Builtin); let num = num_lit().map(Lit::Num); let string = string_lit().map(Lit::String); let table = table_lit(expr).map(Lit::Table); - nil.or(r#true).or(r#false).or(num).or(string).or(table) + nil.or(r#true) + .or(r#false) + .or(builtin) + .or(num) + .or(string) + .or(table) }