diff --git a/src/function/mod.rs b/src/function/mod.rs index ceb36e9..ad4b7ca 100644 --- a/src/function/mod.rs +++ b/src/function/mod.rs @@ -2,8 +2,9 @@ use std::{collections::HashMap, marker::PhantomData}; use crate::{ env::Env, + pest_parser::FuncHolder, statement::Statement, - value::{FromValue, Value}, pest_parser::FuncHolder, + value::{FromValue, Value}, }; mod function_impl; @@ -44,7 +45,7 @@ impl FunctionMap { ); } - pub fn insert_holder(&mut self, holder:FuncHolder) { + pub fn insert_holder(&mut self, holder: FuncHolder) { for f in holder { self.insert_interpreter(&f.0, f.1, f.2); } @@ -89,13 +90,13 @@ impl, P> Function for IntoFunction { } } -pub struct InterpreterFunction { +struct InterpreterFunction { parameters: Vec, body: Vec, } impl InterpreterFunction { - pub fn new(parameters: Vec, body: Vec) -> Self { + fn new(parameters: Vec, body: Vec) -> Self { InterpreterFunction { parameters, body } } } diff --git a/src/grammar.pest b/src/grammar.pest index 6be1930..66a815d 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -4,7 +4,7 @@ COMMENT = _{ "/*" ~ (!"*/" ~ ANY)* ~ "*/" | "//" ~ (!NEWLINE ~ ANY)* } number = @{ "-"? ~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*) - ~ ("." ~ ASCII_DIGIT*)? + ~ ("." ~ ASCII_DIGIT+)? ~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)? } @@ -34,7 +34,9 @@ parens = { "(" ~ expression ~ ")" } const_value = { number | string | char | boolean } -value = { const_value | call | identifier | parens } +value = { (const_value | call | identifier | parens) ~ method_call } + +method_call = { (("." ~ identifier ~ call_params) ~ method_call)? } expression = { equality } diff --git a/src/pest_parser.rs b/src/pest_parser.rs index 7075d93..220dcdf 100644 --- a/src/pest_parser.rs +++ b/src/pest_parser.rs @@ -138,6 +138,7 @@ fn handle_rules(mut p: pest::iterators::Pairs) -> (Statement, FuncHolder) match pair.as_rule() { Rule::expression => { let mut inner = pair.into_inner(); + println!("{:?}", inner); let expr = parse_expression(inner.next().unwrap()); if let Some(c) = inner.next() { let mut inner = c.into_inner(); @@ -194,13 +195,38 @@ fn handle_rules(mut p: pest::iterators::Pairs) -> (Statement, FuncHolder) } } Rule::value => { - let inner = pair.into_inner().next().unwrap(); - parse_value(inner) + let mut inner = pair.into_inner(); + let v = parse_value(inner.next().unwrap()); + if let Some((name, args)) = method_call(inner.next().unwrap()) { + Expression::CallMethod(Box::new(v), name, args) + } else { + v + } } _ => unreachable!(), } } + fn method_call(pair: Pair) -> Option<(String, Vec)> { + match pair.as_rule() { + Rule::method_call => { + let mut inner = pair.into_inner(); + if let Some(name) = inner.next() { + let args = inner + .next() + .unwrap() + .into_inner() + .map(parse_expression) + .collect(); + Some((name.as_str().to_string(), args)) + } else { + None + } + } + _ => None, + } + } + fn parse_value(pair: Pair) -> Expression { match pair.as_rule() { Rule::const_value => { diff --git a/src/value.rs b/src/value/mod.rs similarity index 97% rename from src/value.rs rename to src/value/mod.rs index ca947ab..0c01363 100644 --- a/src/value.rs +++ b/src/value/mod.rs @@ -88,6 +88,10 @@ impl Value { pub fn inner_functions(&self) -> Option { if let Self::Custom(c) = self { c.functions() + } else if let Self::Int(_) = self { + let mut m = FunctionMap::new(); + m.insert_native("is_42", |i: i32| i == 42); + Some(m) } else { None } diff --git a/test.foo b/test.foo index 285353f..3f6ab67 100644 --- a/test.foo +++ b/test.foo @@ -1,20 +1,2 @@ - -foo(); - -def foo() { - print("hello, world!"); -} - -let x = 10; -let y = x-5; - -print(y); -print( edit_foo(native_test()) ); - -// Parameter 0 was not of type sunflower::Foo, it was string -// fancy error isn't it? -// edit_foo("hello"); - -// this doesnt work yet :(((( -// print(10.eq(20)); -print(eq(10, 10)); \ No newline at end of file +print("hello".eq("world")); +print((40 + 2).is_42() == true);