error when reserved function name is used for a user defined function
This commit is contained in:
parent
d766ec775a
commit
73d8f6182f
4 changed files with 23 additions and 11 deletions
|
|
@ -18,6 +18,7 @@ use crate::value::Value;
|
||||||
use crate::{DATE_FORMAT_TIMEZONE, Expr, Stmt, SymbolTable};
|
use crate::{DATE_FORMAT_TIMEZONE, Expr, Stmt, SymbolTable};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use crate::builtins::globals::GLOBAL_FUNCTIONS;
|
||||||
|
|
||||||
pub fn compile(
|
pub fn compile(
|
||||||
path: Option<&str>,
|
path: Option<&str>,
|
||||||
|
|
@ -235,6 +236,9 @@ impl AstCompiler {
|
||||||
|
|
||||||
fn function_declaration(&mut self, symbol_table: &mut SymbolTable) -> Stmt {
|
fn function_declaration(&mut self, symbol_table: &mut SymbolTable) -> Stmt {
|
||||||
let name_token = self.consume(&Identifier, Expected("function name."))?;
|
let name_token = self.consume(&Identifier, Expected("function name."))?;
|
||||||
|
if GLOBAL_FUNCTIONS.contains_key(name_token.lexeme.as_str()) {
|
||||||
|
return Err(self.raise(CompilerError::ReservedFunctionName(name_token.lexeme.clone())))
|
||||||
|
}
|
||||||
self.consume(&LeftParen, Expected("'(' after function name."))?;
|
self.consume(&LeftParen, Expected("'(' after function name."))?;
|
||||||
let mut parameters = vec![];
|
let mut parameters = vec![];
|
||||||
while !self.check(&RightParen) {
|
while !self.check(&RightParen) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::compiler::{compile, run};
|
use crate::compiler::{compile, run};
|
||||||
use crate::errors::CompilerError::IllegalArgumentsException;
|
use crate::errors::CompilerError::{IllegalArgumentsException, ReservedFunctionName};
|
||||||
use crate::errors::CompilerErrorAtLine;
|
use crate::errors::CompilerErrorAtLine;
|
||||||
use crate::errors::RuntimeError::{IllegalArgumentException, IndexOutOfBounds};
|
use crate::errors::RuntimeError::{IllegalArgumentException, IndexOutOfBounds};
|
||||||
use crate::errors::TipiLangError::{Compiler, Runtime};
|
use crate::errors::TipiLangError::{Compiler, Runtime};
|
||||||
|
|
@ -417,6 +417,12 @@ sum
|
||||||
assert!(DateTime::parse_from_str(&date_time_string, DATE_FORMAT_TIMEZONE).is_ok());
|
assert!(DateTime::parse_from_str(&date_time_string, DATE_FORMAT_TIMEZONE).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn global_fns_are_not_allowed() {
|
||||||
|
let value = run(r#"fn now():"#);
|
||||||
|
assert_eq!(value, Err(Compiler(CompilerErrorAtLine { error: ReservedFunctionName("now".to_string()), line: 1 })));
|
||||||
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn package() {
|
// fn package() {
|
||||||
// assert_eq!(run(r#"a.b.c()"#), Ok(Value::U32(48)));
|
// assert_eq!(run(r#"a.b.c()"#), Ok(Value::U32(48)));
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,10 @@ pub fn map_underlying() -> fn(std::io::Error) -> TipiLangError {
|
||||||
|
|
||||||
|
|
||||||
pub fn compile(src: &str) -> Result<HashMap<String, AsmChunk>, TipiLangError> {
|
pub fn compile(src: &str) -> Result<HashMap<String, AsmChunk>, TipiLangError> {
|
||||||
let tokens = compiler::scan_pass::scan(src)?;
|
let tokens = scan_pass::scan(src)?;
|
||||||
let mut asm_registry = HashMap::new();
|
let mut asm_registry = HashMap::new();
|
||||||
let mut symbol_table = HashMap::new();
|
let mut symbol_table = HashMap::new();
|
||||||
let ast = compiler::ast_pass::compile(None, tokens, &mut symbol_table)?;
|
let ast = ast_pass::compile(None, tokens, &mut symbol_table)?;
|
||||||
symbol_builder::build("", &ast, &mut symbol_table);
|
symbol_builder::build("", &ast, &mut symbol_table);
|
||||||
assembly_pass::compile(None, &ast, &symbol_table, &mut asm_registry)?;
|
assembly_pass::compile(None, &ast, &symbol_table, &mut asm_registry)?;
|
||||||
Ok(asm_registry)
|
Ok(asm_registry)
|
||||||
|
|
@ -57,9 +57,9 @@ pub fn compile(src: &str) -> Result<HashMap<String, AsmChunk>, TipiLangError> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn run(src: &str) -> Result<crate::value::Value, TipiLangError> {
|
pub(crate) fn run(src: &str) -> Result<crate::value::Value, TipiLangError> {
|
||||||
let tokens = compiler::scan_pass::scan(src)?;
|
let tokens = scan_pass::scan(src)?;
|
||||||
let mut symbol_table = HashMap::new();
|
let mut symbol_table = HashMap::new();
|
||||||
let ast = compiler::ast_pass::compile(None, tokens, &mut symbol_table)?;
|
let ast = ast_pass::compile(None, tokens, &mut symbol_table)?;
|
||||||
symbol_builder::build("", &ast, &mut symbol_table);
|
symbol_builder::build("", &ast, &mut symbol_table);
|
||||||
let mut asm_registry = HashMap::new();
|
let mut asm_registry = HashMap::new();
|
||||||
assembly_pass::compile(None, &ast, &symbol_table, &mut asm_registry)?;
|
assembly_pass::compile(None, &ast, &symbol_table, &mut asm_registry)?;
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,14 @@ pub enum TipiLangError {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug, PartialEq)]
|
#[derive(Error, Debug, PartialEq)]
|
||||||
pub struct CompilerErrorAtLine{
|
pub struct CompilerErrorAtLine {
|
||||||
pub error: CompilerError,
|
pub error: CompilerError,
|
||||||
pub line: usize
|
pub line: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompilerErrorAtLine {
|
impl CompilerErrorAtLine {
|
||||||
pub(crate) fn raise(error:CompilerError, line: usize) -> Self{
|
pub(crate) fn raise(error: CompilerError, line: usize) -> Self {
|
||||||
Self {error, line}
|
Self { error, line }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +70,9 @@ pub enum CompilerError {
|
||||||
#[error("Illegal argument: '{0}' cannot be indexed")]
|
#[error("Illegal argument: '{0}' cannot be indexed")]
|
||||||
IllegalTypeToIndex(String),
|
IllegalTypeToIndex(String),
|
||||||
#[error("The number of of arguments for {0} is not correct. Should be {1}, got {2}")]
|
#[error("The number of of arguments for {0} is not correct. Should be {1}, got {2}")]
|
||||||
IllegalArgumentsException(String,usize,usize),
|
IllegalArgumentsException(String, usize, usize),
|
||||||
|
#[error("Function name {0} is a global function and cannot be used here.")]
|
||||||
|
ReservedFunctionName(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug, PartialEq)]
|
#[derive(Error, Debug, PartialEq)]
|
||||||
|
|
@ -84,7 +86,7 @@ pub enum RuntimeError {
|
||||||
#[error("Function {0} not found")]
|
#[error("Function {0} not found")]
|
||||||
FunctionNotFound(String),
|
FunctionNotFound(String),
|
||||||
#[error("The number of of arguments for {0} is not correct. Should be {1}, got {2}")]
|
#[error("The number of of arguments for {0} is not correct. Should be {1}, got {2}")]
|
||||||
IllegalArgumentsException(String,usize,usize),
|
IllegalArgumentsException(String, usize, usize),
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
IllegalArgumentException(String),
|
IllegalArgumentException(String),
|
||||||
#[error("Expected {0}")]
|
#[error("Expected {0}")]
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue