Compare commits
No commits in common. "2184f7e654fab17f25569f323f14426a9d608a0b" and "a6bff95d243df878765ddbc31531260bb56fe8f3" have entirely different histories.
2184f7e654
...
a6bff95d24
@ -3,7 +3,6 @@
|
|||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- Parse __more__ binary operators
|
- Parse __more__ binary operators
|
||||||
- Parse `Type name = value` bindings
|
|
||||||
- Parse more complex bindings
|
- Parse more complex bindings
|
||||||
- Watch mode
|
- Watch mode
|
||||||
- Improve error messages
|
- Improve error messages
|
||||||
@ -21,8 +20,8 @@
|
|||||||
## v0.0.10
|
## v0.0.10
|
||||||
|
|
||||||
- [x] Parse function call parameters
|
- [x] Parse function call parameters
|
||||||
- [x] Codegen function call parameters
|
- [ ] Codegen function call parameters
|
||||||
- [x] Parse function declaration arguments (Type id)
|
- [ ] Parse function declaration arguments
|
||||||
- [ ] Begin work on semantic analysis
|
- [ ] Begin work on semantic analysis
|
||||||
- [ ] Symbol table
|
- [ ] Symbol table
|
||||||
- [ ] Typecheck bindings
|
- [ ] Typecheck bindings
|
||||||
|
@ -4,8 +4,6 @@ use super::Transpilable;
|
|||||||
|
|
||||||
impl Transpilable for FunctionCall {
|
impl Transpilable for FunctionCall {
|
||||||
fn transpile(&self) -> String {
|
fn transpile(&self) -> String {
|
||||||
let parameters = &self.arguments.arguments.iter().map(|expr| expr.transpile()).collect::<Vec<_>>().join(", ");
|
format!("{}()", self.function.transpile())
|
||||||
|
|
||||||
format!("{}({})", self.function.transpile(), parameters)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ use super::Expression;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FunctionCall {
|
pub struct FunctionCall {
|
||||||
pub function: Box<Expression>,
|
pub function: Box<Expression>,
|
||||||
pub arguments: Box<ArgumentsList>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -29,11 +29,6 @@ pub struct Block {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ParamsList {}
|
pub struct ParamsList {}
|
||||||
|
|
||||||
pub struct Parameter {
|
|
||||||
pub identifier: Box<String>,
|
|
||||||
pub datatype: Box<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Expression {
|
pub enum Expression {
|
||||||
Number(Box<String>),
|
Number(Box<String>),
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
lexic::token::Token,
|
lexic::token::Token,
|
||||||
syntax::{
|
syntax::{
|
||||||
ast::{
|
ast::{functions::FunctionCall, Expression},
|
||||||
functions::{ArgumentsList, FunctionCall},
|
|
||||||
Expression,
|
|
||||||
},
|
|
||||||
functions::arguments_list,
|
functions::arguments_list,
|
||||||
ParseResult,
|
ParseResult,
|
||||||
},
|
},
|
||||||
@ -23,7 +20,7 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()>
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Parse arguments list
|
// Parse arguments list
|
||||||
let (arguments, next_pos) = match arguments_list::try_parse(tokens, next_pos) {
|
let (_args_list, next_pos) = match arguments_list::try_parse(tokens, next_pos) {
|
||||||
ParseResult::Ok(args, next) => (args, next),
|
ParseResult::Ok(args, next) => (args, next),
|
||||||
ParseResult::Err(err) => return ParseResult::Err(err),
|
ParseResult::Err(err) => return ParseResult::Err(err),
|
||||||
_ => {
|
_ => {
|
||||||
@ -33,11 +30,13 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()>
|
|||||||
|
|
||||||
let fun_call = FunctionCall {
|
let fun_call = FunctionCall {
|
||||||
function: Box::new(primary_expr),
|
function: Box::new(primary_expr),
|
||||||
arguments: Box::new(arguments),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ParseResult::Ok(Expression::FunctionCall(fun_call), next_pos)
|
ParseResult::Ok(Expression::FunctionCall(fun_call), next_pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {}
|
mod test {
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -4,10 +4,7 @@ use crate::{
|
|||||||
syntax::utils::parse_token_type,
|
syntax::utils::parse_token_type,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{ast::ParamsList, ParseResult};
|
||||||
ast::{Parameter, ParamsList},
|
|
||||||
utils, ParseResult,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn parse_params_list<'a>(
|
pub fn parse_params_list<'a>(
|
||||||
tokens: &'a Vec<Token>,
|
tokens: &'a Vec<Token>,
|
||||||
@ -24,36 +21,6 @@ pub fn parse_params_list<'a>(
|
|||||||
};
|
};
|
||||||
current_pos = next_pos;
|
current_pos = next_pos;
|
||||||
|
|
||||||
// Parse parameters definitions, separated by commas
|
|
||||||
let mut parameters = Vec::<Parameter>::new();
|
|
||||||
loop {
|
|
||||||
let (next_parameter, next_pos) = match parse_param_definition(tokens, current_pos) {
|
|
||||||
ParseResult::Ok(parameter, next_pos) => (parameter, next_pos),
|
|
||||||
ParseResult::Err(error) => {
|
|
||||||
return ParseResult::Err(error);
|
|
||||||
}
|
|
||||||
_ => break,
|
|
||||||
};
|
|
||||||
current_pos = next_pos;
|
|
||||||
parameters.push(next_parameter);
|
|
||||||
|
|
||||||
// Parse comma. This also parses a trailing comma
|
|
||||||
match parse_token_type(tokens, current_pos, TokenType::Comma) {
|
|
||||||
ParseResult::Ok(_, next) => {
|
|
||||||
current_pos = next;
|
|
||||||
}
|
|
||||||
// This should never happen
|
|
||||||
ParseResult::Err(err) => return ParseResult::Err(err),
|
|
||||||
ParseResult::Mismatch(_) => {
|
|
||||||
// Something other than a comma was found. It must be a closing paren )
|
|
||||||
// Still, break the loop, assume there are no more arguments
|
|
||||||
// TODO: This could be a good place to write a detailed error?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ParseResult::Unmatched => break,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse closing paren
|
// Parse closing paren
|
||||||
let (_closing_paren, next_pos) =
|
let (_closing_paren, next_pos) =
|
||||||
match parse_token_type(tokens, current_pos, TokenType::RightParen) {
|
match parse_token_type(tokens, current_pos, TokenType::RightParen) {
|
||||||
@ -78,60 +45,3 @@ pub fn parse_params_list<'a>(
|
|||||||
|
|
||||||
ParseResult::Ok(ParamsList {}, current_pos)
|
ParseResult::Ok(ParamsList {}, current_pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_param_definition<'a>(
|
|
||||||
tokens: &'a Vec<Token>,
|
|
||||||
pos: usize,
|
|
||||||
) -> ParseResult<Parameter, &Token> {
|
|
||||||
// Parse a single parameter definition of the form:
|
|
||||||
// - Type identifier
|
|
||||||
// There will be more constructs in the future, like:
|
|
||||||
// - Type identifier = default_value
|
|
||||||
// - FunctionType identifier
|
|
||||||
// - Pattern identifier (e.g. Some[String] value)?
|
|
||||||
|
|
||||||
let mut current_pos = pos;
|
|
||||||
let (datatype, next_pos) =
|
|
||||||
match utils::parse_token_type(tokens, current_pos, TokenType::Datatype) {
|
|
||||||
ParseResult::Ok(token, next) => (token, next),
|
|
||||||
ParseResult::Err(err) => {
|
|
||||||
return ParseResult::Err(err);
|
|
||||||
}
|
|
||||||
// If there is no datatype this construction doesn't apply.
|
|
||||||
// Return a mismatch and let the caller handle it
|
|
||||||
ParseResult::Mismatch(t) => return ParseResult::Mismatch(t),
|
|
||||||
ParseResult::Unmatched => return ParseResult::Unmatched,
|
|
||||||
};
|
|
||||||
current_pos = next_pos;
|
|
||||||
|
|
||||||
let (identifier, next_pos) =
|
|
||||||
match utils::parse_token_type(tokens, current_pos, TokenType::Identifier) {
|
|
||||||
ParseResult::Ok(token, next) => (token, next),
|
|
||||||
ParseResult::Err(err) => {
|
|
||||||
return ParseResult::Err(err);
|
|
||||||
}
|
|
||||||
// However, if we fail to parse an identifier, it's an error
|
|
||||||
ParseResult::Mismatch(_) => {
|
|
||||||
return ParseResult::Err(SyntaxError {
|
|
||||||
reason: String::from("Expected an identifier for the parameter."),
|
|
||||||
error_start: tokens[pos].position,
|
|
||||||
error_end: tokens[pos].get_end_position(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ParseResult::Unmatched => {
|
|
||||||
return ParseResult::Err(SyntaxError {
|
|
||||||
reason: String::from("Expected an identifier for the parameter."),
|
|
||||||
error_start: tokens[pos].position,
|
|
||||||
error_end: tokens[pos].get_end_position(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ParseResult::Ok(
|
|
||||||
Parameter {
|
|
||||||
identifier: Box::new(identifier.value.clone()),
|
|
||||||
datatype: Box::new(datatype.value.clone()),
|
|
||||||
},
|
|
||||||
next_pos,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user