Add builtins to ast and parse them
This commit is contained in:
parent
4fdce864d3
commit
a82b625631
3 changed files with 58 additions and 20 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use crate::builtin::Builtin;
|
||||||
use crate::span::{HasSpan, Span};
|
use crate::span::{HasSpan, Span};
|
||||||
|
|
||||||
use super::basic::{Ident, Space};
|
use super::basic::{Ident, Space};
|
||||||
|
|
@ -127,6 +128,10 @@ pub enum Lit {
|
||||||
/// - `false`
|
/// - `false`
|
||||||
Bool(bool, Span),
|
Bool(bool, Span),
|
||||||
|
|
||||||
|
/// - `'get`
|
||||||
|
/// - `'destructure`
|
||||||
|
Builtin(Builtin, Span),
|
||||||
|
|
||||||
/// See [`NumLit`].
|
/// See [`NumLit`].
|
||||||
Num(NumLit),
|
Num(NumLit),
|
||||||
|
|
||||||
|
|
@ -142,6 +147,7 @@ impl fmt::Debug for Lit {
|
||||||
match self {
|
match self {
|
||||||
Self::Nil(_) => write!(f, "l#nil"),
|
Self::Nil(_) => write!(f, "l#nil"),
|
||||||
Self::Bool(b, _) => write!(f, "l#{b:?}"),
|
Self::Bool(b, _) => write!(f, "l#{b:?}"),
|
||||||
|
Self::Builtin(b, _) => write!(f, "l#{b:?}"),
|
||||||
Self::Num(n) => write!(f, "l#{n:?}"),
|
Self::Num(n) => write!(f, "l#{n:?}"),
|
||||||
Self::String(s) => write!(f, "l#{s:?}"),
|
Self::String(s) => write!(f, "l#{s:?}"),
|
||||||
Self::Table(t) => {
|
Self::Table(t) => {
|
||||||
|
|
@ -157,6 +163,7 @@ impl HasSpan for Lit {
|
||||||
match self {
|
match self {
|
||||||
Lit::Nil(span) => *span,
|
Lit::Nil(span) => *span,
|
||||||
Lit::Bool(_, span) => *span,
|
Lit::Bool(_, span) => *span,
|
||||||
|
Lit::Builtin(_, span) => *span,
|
||||||
Lit::Num(n) => n.span(),
|
Lit::Num(n) => n.span(),
|
||||||
Lit::String(s) => s.span(),
|
Lit::String(s) => s.span(),
|
||||||
Lit::Table(t) => t.span(),
|
Lit::Table(t) => t.span(),
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,31 @@
|
||||||
// Possible future built-ins
|
use std::fmt;
|
||||||
//
|
|
||||||
// #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
|
|
||||||
|
|
||||||
/// Built-in operations
|
/// Built-in operations
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum Builtin {}
|
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"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,24 @@
|
||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
|
|
||||||
use crate::ast::{Expr, Lit, NumLit, NumLitStr, StringLit, TableLit, TableLitElem};
|
use crate::ast::{Expr, Lit, NumLit, NumLitStr, StringLit, TableLit, TableLitElem};
|
||||||
|
use crate::builtin::Builtin;
|
||||||
|
|
||||||
use super::basic::{ident, space, Error};
|
use super::basic::{ident, space, Error};
|
||||||
|
|
||||||
|
fn builtin_lit() -> impl Parser<char, Builtin, Error = Error> {
|
||||||
|
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<char, (i64, NumLitStr), Error = Error> + Clone {
|
fn num_lit_str_radix(radix: u32) -> impl Parser<char, (i64, NumLitStr), Error = Error> + Clone {
|
||||||
// Minimum amount of digits required to represent i64::MAX. The rest of this
|
// 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
|
// 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 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#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 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 num = num_lit().map(Lit::Num);
|
||||||
let string = string_lit().map(Lit::String);
|
let string = string_lit().map(Lit::String);
|
||||||
let table = table_lit(expr).map(Lit::Table);
|
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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue