Add method syntax

This commit is contained in:
Julius 2022-07-03 23:13:12 +02:00
parent 4700af0e54
commit 68bcdb987e
Signed by: j00lz
GPG key ID: AF241B0AA237BBA2
5 changed files with 43 additions and 28 deletions

View file

@ -2,8 +2,9 @@ use std::{collections::HashMap, marker::PhantomData};
use crate::{ use crate::{
env::Env, env::Env,
pest_parser::FuncHolder,
statement::Statement, statement::Statement,
value::{FromValue, Value}, pest_parser::FuncHolder, value::{FromValue, Value},
}; };
mod function_impl; 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 { for f in holder {
self.insert_interpreter(&f.0, f.1, f.2); self.insert_interpreter(&f.0, f.1, f.2);
} }
@ -89,13 +90,13 @@ impl<F: NativeFunction<P>, P> Function for IntoFunction<F, P> {
} }
} }
pub struct InterpreterFunction { struct InterpreterFunction {
parameters: Vec<String>, parameters: Vec<String>,
body: Vec<Statement>, body: Vec<Statement>,
} }
impl InterpreterFunction { impl InterpreterFunction {
pub fn new(parameters: Vec<String>, body: Vec<Statement>) -> Self { fn new(parameters: Vec<String>, body: Vec<Statement>) -> Self {
InterpreterFunction { parameters, body } InterpreterFunction { parameters, body }
} }
} }

View file

@ -4,7 +4,7 @@ COMMENT = _{ "/*" ~ (!"*/" ~ ANY)* ~ "*/" | "//" ~ (!NEWLINE ~ ANY)* }
number = @{ number = @{
"-"? "-"?
~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*) ~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*)
~ ("." ~ ASCII_DIGIT*)? ~ ("." ~ ASCII_DIGIT+)?
~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)? ~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)?
} }
@ -34,7 +34,9 @@ parens = { "(" ~ expression ~ ")" }
const_value = { number | string | char | boolean } 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 } expression = { equality }

View file

@ -138,6 +138,7 @@ fn handle_rules(mut p: pest::iterators::Pairs<Rule>) -> (Statement, FuncHolder)
match pair.as_rule() { match pair.as_rule() {
Rule::expression => { Rule::expression => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
println!("{:?}", inner);
let expr = parse_expression(inner.next().unwrap()); let expr = parse_expression(inner.next().unwrap());
if let Some(c) = inner.next() { if let Some(c) = inner.next() {
let mut inner = c.into_inner(); let mut inner = c.into_inner();
@ -194,13 +195,38 @@ fn handle_rules(mut p: pest::iterators::Pairs<Rule>) -> (Statement, FuncHolder)
} }
} }
Rule::value => { Rule::value => {
let inner = pair.into_inner().next().unwrap(); let mut inner = pair.into_inner();
parse_value(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!(), _ => unreachable!(),
} }
} }
fn method_call(pair: Pair<Rule>) -> Option<(String, Vec<Expression>)> {
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<Rule>) -> Expression { fn parse_value(pair: Pair<Rule>) -> Expression {
match pair.as_rule() { match pair.as_rule() {
Rule::const_value => { Rule::const_value => {

View file

@ -88,6 +88,10 @@ impl Value {
pub fn inner_functions(&self) -> Option<FunctionMap> { pub fn inner_functions(&self) -> Option<FunctionMap> {
if let Self::Custom(c) = self { if let Self::Custom(c) = self {
c.functions() 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 { } else {
None None
} }

View file

@ -1,20 +1,2 @@
print("hello".eq("world"));
foo(); print((40 + 2).is_42() == true);
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));