diff --git a/src/ast/mod.rs b/src/ast/mod.rs index fcc831e0..ed14ee3a 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -8,6 +8,7 @@ use crate::ast::eval_op::*; use crate::ast::Expr::{Apply, Const}; use crate::ast::op::Op; use crate::error::CozoError; +use crate::typing::Typing; use crate::value::Value; mod eval_op; @@ -32,6 +33,32 @@ lazy_static! { }; } +pub struct Col { + pub name: String, + pub typ: Typing, + pub default: Option>, +} + +pub enum TableDef { + Node { + name: String, + keys: Vec, + cols: Vec, + }, + Edge { + src: String, + dst: String, + name: String, + keys: Vec, + cols: Vec, + }, + Columns { + attached: String, + name: String, + cols: Vec, + }, +} + #[derive(PartialEq, Debug)] pub enum Expr<'a> { @@ -93,28 +120,6 @@ fn build_expr_infix<'a>(lhs: Result, CozoError>, op: Pair, rhs: R _ => unreachable!() }; Ok(Apply(op, vec![lhs, rhs])) - /* - /* - Rule::op_or => { - match (a, b) { - (Value::Null, Value::Null) => Ok(Const(Value::Null)), - (Value::Null, Value::Bool(b)) => Ok(Const(Value::Bool(b))), - (Value::Bool(b), Value::Null) => Ok(Const(Value::Bool(b))), - (Value::Bool(a), Value::Bool(b)) => Ok(Const(Value::Bool(a || b))), - (a, b) => Err(CozoError::InfixTypeMismatch { op: rule, lhs: a.into_owned(), rhs: b.into_owned() }) - } - } - Rule::op_and => { - match (a, b) { - (Value::Null, Value::Null) => Ok(Const(Value::Null)), - (Value::Null, Value::Bool(_)) => Ok(Const(Value::Null)), - (Value::Bool(_), Value::Null) => Ok(Const(Value::Null)), - (Value::Bool(a), Value::Bool(b)) => Ok(Const(Value::Bool(a && b))), - (a, b) => Err(CozoError::InfixTypeMismatch { op: rule, lhs: a.into_owned(), rhs: b.into_owned() }) - } - } - */ - */ } #[inline] @@ -122,6 +127,11 @@ fn parse_int(s: &str, radix: u32) -> i64 { i64::from_str_radix(&s[2..].replace('_', ""), radix).unwrap() } +#[inline] +fn parse_raw_string(pairs: Pairs) -> Result { + Ok(pairs.into_iter().next().unwrap().as_str().to_string()) +} + #[inline] fn parse_quoted_string(pairs: Pairs) -> Result { let mut ret = String::with_capacity(pairs.as_str().len()); @@ -185,14 +195,6 @@ fn build_expr_primary(pair: Pair) -> Result { let mut inner = pair.into_inner(); let op = inner.next().unwrap().as_rule(); let term = build_expr_primary(inner.next().unwrap())?; - /* - match (op, term) { - (Rule::minus, Const(Value::Int(i))) => Ok(Const(Value::Int(-i))), - (Rule::minus, Const(Value::Float(f))) => Ok(Const(Value::Float(-f))), - (_, Const(term)) => Err(PrefixTypeMismatch { op, term: term.into_owned() }), - (_, _) => unimplemented!() - } - */ Ok(Apply(match op { Rule::negate => Op::Neg, Rule::minus => Op::Minus, @@ -209,6 +211,7 @@ fn build_expr_primary(pair: Pair) -> Result { Rule::boolean => Ok(Const(Value::Bool(pair.as_str() == "true"))), Rule::quoted_string => Ok(Const(Value::OwnString(Box::new(parse_quoted_string(pair.into_inner().next().unwrap().into_inner())?)))), Rule::s_quoted_string => Ok(Const(Value::OwnString(Box::new(parse_s_quoted_string(pair.into_inner().next().unwrap().into_inner())?)))), + Rule::raw_string => Ok(Const(Value::OwnString(Box::new(parse_raw_string(pair.into_inner())?)))), _ => { println!("{:#?}", pair); unimplemented!() @@ -229,6 +232,11 @@ pub fn parse_expr_from_str(inp: &str) -> Result { mod tests { use super::*; + #[test] + fn raw_string() { + println!("{:#?}", parse_expr_from_str(r#####"r#"x"#"#####)) + } + #[test] fn parse_literals() { assert_eq!(parse_expr_from_str("1").unwrap(), Const(Value::Int(1))); @@ -249,6 +257,7 @@ mod tests { assert_eq!(parse_expr_from_str(r#""x \n \ty \"""#).unwrap(), Const(Value::RefString("x \n \ty \""))); assert_eq!(parse_expr_from_str(r#""x'""#).unwrap(), Const(Value::RefString("x'"))); assert_eq!(parse_expr_from_str(r#"'"x"'"#).unwrap(), Const(Value::RefString(r##""x""##))); + assert_eq!(parse_expr_from_str(r#####"r###"x"yz"###"#####).unwrap(), Const(Value::RefString(r##"x"yz"##))); } #[test] diff --git a/src/grammar.pest b/src/grammar.pest index 85df5e5d..b59ac75f 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -10,10 +10,8 @@ COMMENT = _{(BLOCK_COMMENT | LINE_COMMENT)} // identifiers -normal_ident = @{XID_START ~ ("_" | XID_CONTINUE)*} -special_ident = @{"_" ~ ("_" | XID_CONTINUE)*} -param_ident = @{"$" ~ ("_" | XID_CONTINUE)+} -ident = { normal_ident | special_ident | param_ident} +ident = @{("_" | XID_START) ~ ("_" | XID_CONTINUE)*} +param = @{"$" ~ ("_" | XID_CONTINUE)+} // literals @@ -34,9 +32,20 @@ s_char = { | "\\" ~ ("\'" | "\\" | "/" | "b" | "f" | "n" | "r" | "t") | "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4}) } +raw_string = { + "r" ~ PUSH("#"*) ~ "\"" // push the number signs onto the stack + ~ raw_string_inner + ~ "\"" ~ POP // match a quotation mark and the number signs +} +raw_string_inner = { + ( + !("\"" ~ PEEK) // unless the next character is a quotation mark + // followed by the correct amount of number signs, + ~ ANY // consume one character + )* +} - -string = _{(s_quoted_string | quoted_string)} +string = _{(raw_string | s_quoted_string | quoted_string)} // Boolean and null @@ -98,12 +107,12 @@ unary_op = _{ minus | negate } minus = { "-" } negate = { "!" } -term = { (grouping | literal | normal_ident | param_ident | list | dict) ~ (call | accessor | index_accessor)* } -call = {"." ~ (normal_ident | special_ident) ~ "(" ~ argument* ~ ")"} -accessor = {"." ~ (normal_ident | special_ident)} +term = { (grouping | literal | ident | param | list | dict) ~ (call | accessor | index_accessor)* } +call = {"." ~ ident ~ "(" ~ argument* ~ ")"} +accessor = {"." ~ ident} index_accessor = {"[" ~ expr ~ "]"} argument = _{(kw_arg | pos_arg)} -kw_arg = {normal_ident ~ "=" ~ expr} +kw_arg = {ident ~ "=" ~ expr} pos_arg = { expr } grouping = { "(" ~ expr ~ ")" } @@ -113,7 +122,7 @@ spreading = {"..." ~ term} dict = { "{" ~ (dict_entry ~ ",")* ~ dict_entry? ~ "}"} dict_entry = _{ spreading | dict_accessor | dict_pair } -dict_accessor = { normal_ident? ~ ("." ~ (normal_ident | special_ident))+ } -dict_pair = {(normal_ident | special_ident | string) ~ ":" ~ expr} +dict_accessor = { ident? ~ ("." ~ ident)+ } +dict_pair = {(ident | string) ~ ":" ~ expr} -scoped_dict = { normal_ident ~ dict } \ No newline at end of file +scoped_dict = { ident ~ dict } \ No newline at end of file diff --git a/src/parser.rs b/src/parser.rs index f505d3a3..d8352e92 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -31,22 +31,20 @@ mod tests { #[test] fn identifiers() { - assert_eq!(Parser::parse(Rule::normal_ident, "x").unwrap().as_str(), "x"); - assert_eq!(Parser::parse(Rule::normal_ident, "x2").unwrap().as_str(), "x2"); - assert_eq!(Parser::parse(Rule::normal_ident, "x_y").unwrap().as_str(), "x_y"); - assert_eq!(Parser::parse(Rule::normal_ident, "x_").unwrap().as_str(), "x_"); - assert_eq!(Parser::parse(Rule::normal_ident, "你好").unwrap().as_str(), "你好"); - assert_eq!(Parser::parse(Rule::normal_ident, "你好123").unwrap().as_str(), "你好123"); + assert_eq!(Parser::parse(Rule::ident, "x").unwrap().as_str(), "x"); + assert_eq!(Parser::parse(Rule::ident, "x2").unwrap().as_str(), "x2"); + assert_eq!(Parser::parse(Rule::ident, "x_y").unwrap().as_str(), "x_y"); + assert_eq!(Parser::parse(Rule::ident, "x_").unwrap().as_str(), "x_"); + assert_eq!(Parser::parse(Rule::ident, "你好").unwrap().as_str(), "你好"); + assert_eq!(Parser::parse(Rule::ident, "你好123").unwrap().as_str(), "你好123"); assert_ne!(Parser::parse(Rule::ident, "x$y").unwrap().as_str(), "x$y"); - assert!(Parser::parse(Rule::normal_ident, "_x").is_err()); - assert!(Parser::parse(Rule::normal_ident, "_").is_err()); assert_eq!(Parser::parse(Rule::ident, "_x").unwrap().as_str(), "_x"); assert_eq!(Parser::parse(Rule::ident, "_").unwrap().as_str(), "_"); - assert!(Parser::parse(Rule::normal_ident, "$x").is_err()); + assert!(Parser::parse(Rule::ident, "$x").is_err()); assert!(Parser::parse(Rule::ident, "$").is_err()); - assert_eq!(Parser::parse(Rule::ident, "$x").unwrap().as_str(), "$x"); + assert_eq!(Parser::parse(Rule::param, "$x").unwrap().as_str(), "$x"); assert!(Parser::parse(Rule::ident, "123x").is_err()); assert!(Parser::parse(Rule::ident, ".x").is_err()); diff --git a/src/value.rs b/src/value.rs index c02db071..c543771c 100644 --- a/src/value.rs +++ b/src/value.rs @@ -11,9 +11,9 @@ use Ordering::{Greater, Less, Equal}; #[repr(u8)] #[derive(Ord, PartialOrd, Eq, PartialEq)] pub enum ValueTag { - NullTag = 0, - BoolTrueTag = 2, - BoolFalseTag = 4, + BoolFalseTag = 0, + NullTag = 2, + BoolTrueTag = 4, FwdEdgeTag = 6, BwdEdgeTag = 8, IntTag = 11,