added boolean support
This commit is contained in:
parent
404916048a
commit
f165dad8f5
|
@ -7,6 +7,7 @@ name = "Yard"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"rand",
|
||||
"regex",
|
||||
]
|
||||
|
||||
|
@ -19,18 +20,77 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.134"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
|
@ -47,3 +107,9 @@ name = "regex-syntax"
|
|||
version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
|
|
@ -8,3 +8,4 @@ edition = "2021"
|
|||
[dependencies]
|
||||
regex = "*"
|
||||
lazy_static = "1.4.0"
|
||||
rand = "0.8.5"
|
|
@ -3,3 +3,4 @@ Yard is an funny programming language compiler and interpreter written in pure R
|
|||
It *will* contain features such as:
|
||||
1. a COMEFROM keyword (inverse goto)
|
||||
2. a ```don't``` code block which never executes
|
||||
3. swapped meaning of "" (for single characters) and '' (now for string literal)
|
|
@ -9,12 +9,10 @@ fn main() {
|
|||
|
||||
let source =
|
||||
r"
|
||||
foo(c) = 3 * c
|
||||
pi = 3.1415926
|
||||
|
||||
main() {
|
||||
x = foo(5 * 6)
|
||||
|
||||
4 * 3
|
||||
}
|
||||
";
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ fn discover_exprs<'a>(functions: &mut Vec<Func<'a>>) {
|
|||
/// parse a single term using a modified shunting yard
|
||||
fn parse_term<'a>(term: &mut VecDeque<Token<'a>>, scope: &mut Scope) {
|
||||
let mut op_stack = vec![];
|
||||
let mut output = VecDeque::new();
|
||||
let mut output = VecDeque::with_capacity(term.len());
|
||||
|
||||
'outer:
|
||||
while let Some(token) = term.pop_front() {
|
||||
|
@ -273,8 +273,10 @@ fn parse_term<'a>(term: &mut VecDeque<Token<'a>>, scope: &mut Scope) {
|
|||
let prec1 = op1.prec();
|
||||
|
||||
if prec1 > prec0 || prec0 == prec1 && op.assoc() == Assoc::Left {
|
||||
output.push_back(op_stack.pop().unwrap())
|
||||
output.push_back(op_stack.pop().unwrap());
|
||||
continue
|
||||
}
|
||||
break
|
||||
},
|
||||
_ => break
|
||||
}
|
||||
|
|
|
@ -2,6 +2,17 @@ use std::collections::{VecDeque};
|
|||
|
||||
#[derive(Debug, Hash, PartialEq, Eq)]
|
||||
pub enum Operator {
|
||||
Or,
|
||||
And,
|
||||
Xor,
|
||||
|
||||
Eq,
|
||||
Lt,
|
||||
Gt,
|
||||
GtEq,
|
||||
LtEq,
|
||||
NotEq,
|
||||
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
|
@ -19,6 +30,17 @@ pub enum Assoc {
|
|||
impl Operator {
|
||||
pub fn parse<'a>(str: &'a str) -> Self {
|
||||
return match str {
|
||||
"|" => Operator::Or,
|
||||
"&" => Operator::And,
|
||||
"^" => Operator::Xor,
|
||||
|
||||
"==" => Operator::Eq,
|
||||
"<" => Operator::Lt,
|
||||
">" => Operator::Gt,
|
||||
"<=" => Operator::LtEq,
|
||||
">=" => Operator::GtEq,
|
||||
"!=" => Operator::NotEq,
|
||||
|
||||
"+" => Operator::Add,
|
||||
"-" => Operator::Sub,
|
||||
"*" => Operator::Mul,
|
||||
|
@ -31,6 +53,17 @@ impl Operator {
|
|||
|
||||
pub fn prec(&self) -> usize {
|
||||
return match self {
|
||||
Operator::Eq => 2,
|
||||
Operator::Lt => 2,
|
||||
Operator::Gt => 2,
|
||||
Operator::LtEq => 2,
|
||||
Operator::GtEq => 2,
|
||||
Operator::NotEq => 2,
|
||||
|
||||
Operator::Or => 0,
|
||||
Operator::Xor => 0,
|
||||
Operator::And => 1,
|
||||
|
||||
Operator::Add => 3,
|
||||
Operator::Sub => 3,
|
||||
|
||||
|
@ -62,9 +95,10 @@ pub enum Token<'a> {
|
|||
Var(&'a str),
|
||||
Arg(&'a str),
|
||||
Assign(&'a str),
|
||||
Bool(bool),
|
||||
}
|
||||
|
||||
const TOKEN_REGEX_SRC: &'static str = r"(#.*)|([A-Za-z_]+)\s*=|([A-Za-z_]+)|(\d*\.?\d+)|([+\-*/=])|([(){}])|(\n)";
|
||||
const TOKEN_REGEX_SRC: &'static str = r"(#.*)|(true|false|yes|no|maybe)|([A-Za-z_]+)\s*=|([A-Za-z_]+)|(\d*\.?\d+)|(!=|==|<=|<=|[&|+\-*/<>])|([(){}])|(\n)";
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref TOKEN_REGEX: regex::Regex = regex::Regex::new(TOKEN_REGEX_SRC).unwrap();
|
||||
|
@ -86,12 +120,13 @@ pub fn tokenize<'a>(source: &'a str) -> VecDeque<Token<'a>> {
|
|||
// if we have a match, save it as token
|
||||
if let Some(mat) = group {
|
||||
tokens.push_back(match i {
|
||||
2 => Token::Assign(mat.as_str()),
|
||||
3 => Token::Word(mat.as_str()),
|
||||
4 => Token::Number(mat.as_str()),
|
||||
5 => Token::Operator(Operator::parse(mat.as_str())),
|
||||
6 => Token::Delemiter(mat.as_str().chars().nth(0).unwrap()),
|
||||
7 => Token::LineBreak,
|
||||
2 => Token::Bool(parse_bool(mat.as_str())),
|
||||
3 => Token::Assign(mat.as_str()),
|
||||
4 => Token::Word(mat.as_str()),
|
||||
5 => Token::Number(mat.as_str()),
|
||||
6 => Token::Operator(Operator::parse(mat.as_str())),
|
||||
7 => Token::Delemiter(mat.as_str().chars().nth(0).unwrap()),
|
||||
8 => Token::LineBreak,
|
||||
|
||||
_ => panic!("Unknown match to tokenize: {}", mat.as_str())
|
||||
});
|
||||
|
@ -101,3 +136,12 @@ pub fn tokenize<'a>(source: &'a str) -> VecDeque<Token<'a>> {
|
|||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
fn parse_bool(text: &str) -> bool {
|
||||
return match text.to_ascii_lowercase().as_str() {
|
||||
"true" | "ye" => true,
|
||||
"false" |"no" => false,
|
||||
"maybe" => rand::random(),
|
||||
_ => panic!("Not a recognized boolean {text}")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue