diff --git a/examples/array.pr b/examples/array.pr new file mode 100644 index 0000000..abd9097 --- /dev/null +++ b/examples/array.pr @@ -0,0 +1,68 @@ + +for: (from, to, f) => { + index: from; + loop { + if not(inf(index, to)) break true; + f(index); + index <- add(index, 1) + } +}; + +array_new: () => { + r: obj(); + r <- set(r, "len", 0); + r +}; + +array_len: (self) => { + get(self, "len") +}; + +array_get: (self, index) => { + get(self, str(index)) +}; + +array_push: (self, e) => { + i: array_len(self); + self <- set(self, str(i), e); + + len: add (i, 1); + self <- set(self, "len", len); + self +}; + +array_pop: (self) => { + l: array_len(self); + if eq(l, 0) return false; + + i: sub(l, 1); + e: array_get(self, i); + self <- set(self, str(i), false); + + r: obj(); + r <- set(r, "tail", e); + r <- set(r, "rest", self); + r +}; + +array_print: (self) => { + l: array_len(self); + r: "["; + for(0, l, (i) => { + r <- add(r, array_get(self, i)); + r <- add(r, ", ") + }); + r <- add(r, "]"); + out(r) +}; + +main: () => { + a: array_new(); + a <- array_push(a, 1); + a <- array_push(a, 2); + a <- array_push(a, 3); + a <- array_push(a, 4); + array_print(a) +}; + +main(); diff --git a/src/execution_tree/parser.rs b/src/execution_tree/parser.rs index cf0c394..d7960c0 100644 --- a/src/execution_tree/parser.rs +++ b/src/execution_tree/parser.rs @@ -187,7 +187,7 @@ impl Parser { parameter_names, } = function_definition; - let parser_scope = parser_scope.make_child_common(); + let parser_scope = parser_scope.make_child_function(); let parameter_ids = parameter_names .into_iter() .map(|name| parser_scope.add_name(name)) @@ -209,7 +209,7 @@ impl Parser { let variable_id = parser_scope .get_variable_id(&name) - .expect("call of undeclared function"); + .expect(&format!("call of undeclared function '{name}'")); let parameters = arguments .into_iter() .map(|argument| self.parse_expression(argument, parser_scope)) diff --git a/src/prelude.rs b/src/prelude.rs index 433e268..a6a3a71 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -132,7 +132,11 @@ fn set(args: Vec) -> Value { let mut object = args.get(0).unwrap().as_object().unwrap().clone(); let name = args.get(1).unwrap().as_string().unwrap().to_string(); let value = args.get(2).unwrap().clone(); - object.insert(name, value); + if let Value::Bool(false) = value { + object.remove(&name); + } else { + object.insert(name, value); + } object.into() } diff --git a/src/syntax_tree/parser.rs b/src/syntax_tree/parser.rs index 64075b6..3ce7100 100644 --- a/src/syntax_tree/parser.rs +++ b/src/syntax_tree/parser.rs @@ -142,7 +142,12 @@ fn test_function_definition_parser() { pub fn function_call_parser(expression: impl AbstractParser) -> impl AbstractParser { let parameters = expression.separated_by(just(',').padded()); name() - .then(parameters.padded().delimited_by(just('('), just(')'))) + .then( + parameters + .padded() + .delimited_by(just('('), just(')')) + .padded(), + ) .map(|(name, arguments)| FnCall { arguments, name }) } diff --git a/src/value.rs b/src/value.rs index fdfe9a4..463e766 100644 --- a/src/value.rs +++ b/src/value.rs @@ -100,13 +100,6 @@ impl Value { } } - pub fn as_object_mut(&mut self) -> Option<&mut HashMap> { - match self { - Self::Object(h) => Some(h), - _ => None, - } - } - pub fn as_function(&self) -> Option<&Function> { match self { Self::Function(function) => Some(function),