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::{
env::Env,
pest_parser::FuncHolder,
statement::Statement,
value::{FromValue, Value}, pest_parser::FuncHolder,
value::{FromValue, Value},
};
mod function_impl;
@ -89,13 +90,13 @@ impl<F: NativeFunction<P>, P> Function for IntoFunction<F, P> {
}
}
pub struct InterpreterFunction {
struct InterpreterFunction {
parameters: Vec<String>,
body: Vec<Statement>,
}
impl InterpreterFunction {
pub fn new(parameters: Vec<String>, body: Vec<Statement>) -> Self {
fn new(parameters: Vec<String>, body: Vec<Statement>) -> Self {
InterpreterFunction { parameters, body }
}
}

View file

@ -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 }

View file

@ -138,6 +138,7 @@ fn handle_rules(mut p: pest::iterators::Pairs<Rule>) -> (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<Rule>) -> (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<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 {
match pair.as_rule() {
Rule::const_value => {

View file

@ -88,6 +88,10 @@ impl Value {
pub fn inner_functions(&self) -> Option<FunctionMap> {
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
}

View file

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