More parsing work
This commit is contained in:
parent
2bc3bee344
commit
f004c19133
|
@ -85,9 +85,8 @@ paramlist ::= '(' ['void' | (type typemod [identifier] ['=' expr] {','
|
|||
virtprop ::= ['private' | 'protected'] type ['&'] identifier '{' {('get' | 'set') ['const'] funcattr (statblock | ';')} '}';
|
||||
func ::= {'shared' | 'external'} ['private' | 'protected'] [((type ['&']) | '~')] identifier paramlist ['const'] funcattr (';' | statblock);
|
||||
funcdef ::= {'external' | 'shared'} 'funcdef' type ['&'] identifier paramlist ';'
|
||||
class ::= {'shared' | 'abstract' | 'final' | 'external'} 'class' identifier
|
||||
class ::= {'shared' | 'abstract' | 'final' | 'external' | 'mixin'} 'class' identifier
|
||||
(';' | ([':' identifier {',' identifier}] '{' {virtprop | func | var | funcdef | class} '}'));
|
||||
mixin ::= 'mixin' class;
|
||||
enum ::= {'shared' | 'external'} 'enum' identifier [ ':' primtype ] (';' | ('{' identifier ['=' expr] {',' identifier ['=' expr]} '}'));
|
||||
import ::= 'import' type ['&'] identifier paramlist funcattr 'from' string ';';
|
||||
typedef ::= 'typedef' (primtype | identifier) identifier ';';
|
||||
|
@ -96,4 +95,4 @@ interfacemethod ::= type ['&'] identifier paramlist ['const'] ';';
|
|||
interface ::= {'external' | 'shared'} 'interface' identifier (';' | ([':' identifier {',' identifier}] '{' {virtprop | interfacemethod} '}'));
|
||||
|
||||
namespace ::= 'namespace' identifier '{' script '}';
|
||||
script ::= {import | enum | typedef | class | mixin | interface | funcdef | virtprop | var | func | namespace | ';'};
|
||||
script ::= {import | enum | typedef | class | interface | funcdef | virtprop | var | func | namespace | ';'};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
mod parsed_funcattr;
|
||||
pub mod parsed_statement;
|
||||
pub mod parsed_type_modifier;
|
||||
mod parser_operators;
|
||||
|
@ -9,6 +10,7 @@ use crate::logger::messages::Message;
|
|||
use crate::logger::messages::Message::UnexpectedToken;
|
||||
use crate::modifiers::{FieldModifier, TypeModifier};
|
||||
use crate::parsing::lexer::lex_tokens::TokenType::CloseBracket;
|
||||
use crate::parsing::parser::parsed_funcattr::FuncAttr;
|
||||
use crate::parsing::parser::parsed_statement::ParsedStatement::{
|
||||
AnonymousCall, ExprPostOp, IndexingOperator,
|
||||
};
|
||||
|
@ -311,37 +313,126 @@ fn parse_interface(
|
|||
}
|
||||
|
||||
fn parse_interface_method(
|
||||
_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
outer_reader: &mut ParseReader,
|
||||
log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
unimplemented!();
|
||||
// interfacemethod ::= type ['&'] identifier paramlist ['const'] ';';
|
||||
let mut reader = outer_reader.create_inner();
|
||||
let return_type = parse_type(&mut reader, log);
|
||||
if return_type.is_none() {
|
||||
return None;
|
||||
}
|
||||
let returns_reference = reader.peek().token_type == TokenType::Ampersand;
|
||||
if returns_reference {
|
||||
reader.next();
|
||||
}
|
||||
let identifier = parse_identifier(&mut reader, log, true);
|
||||
if identifier.is_none() {
|
||||
return None;
|
||||
}
|
||||
let param_list = parse_paramlist(&mut reader, log);
|
||||
if param_list.is_none() {
|
||||
return None;
|
||||
}
|
||||
let is_const = reader.peek().token_type == TokenType::ConstKeyword;
|
||||
if is_const {
|
||||
reader.next();
|
||||
}
|
||||
reader.consume(TokenType::Semicolon, log);
|
||||
|
||||
Some(Box::new(ParsedStatement::InterfaceMethod {
|
||||
return_type: return_type.unwrap(),
|
||||
returns_reference,
|
||||
identifier: identifier.unwrap(),
|
||||
param_list: param_list.unwrap(),
|
||||
is_const,
|
||||
}))
|
||||
}
|
||||
|
||||
fn parse_typedef(
|
||||
_outer_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
reader: &mut ParseReader,
|
||||
log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
unimplemented!();
|
||||
// typedef ::= 'typedef' (primtype | identifier) identifier ';';
|
||||
if reader.peek().token_type != TokenType::TypeDefKeyword {
|
||||
return None;
|
||||
}
|
||||
reader.next();
|
||||
let mut left_type = parse_primtype(reader, log);
|
||||
if left_type.is_none() {
|
||||
let left_type_identifier = parse_identifier(reader, log, false);
|
||||
if left_type_identifier.is_some() {
|
||||
left_type = Some(Box::new(ParsedStatement::DataTypeIdentifier {
|
||||
identifier: left_type_identifier.unwrap(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
let right_type_identifier = parse_identifier(reader, log, false);
|
||||
if right_type_identifier.is_none() {
|
||||
return None;
|
||||
}
|
||||
let right_type = Box::new(ParsedStatement::DataTypeIdentifier {
|
||||
identifier: right_type_identifier.unwrap(),
|
||||
});
|
||||
|
||||
reader.consume(TokenType::Semicolon, log);
|
||||
Some(Box::new(ParsedStatement::TypeDefStatement {
|
||||
from: left_type.unwrap(),
|
||||
to: right_type,
|
||||
}))
|
||||
}
|
||||
|
||||
fn parse_import(
|
||||
_outer_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
reader: &mut ParseReader,
|
||||
log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
unimplemented!();
|
||||
// import ::= 'import' type ['&'] identifier paramlist funcattr 'from' string ';';
|
||||
if reader.peek().token_type != TokenType::ImportKeyword {
|
||||
return None;
|
||||
}
|
||||
reader.next();
|
||||
let import_type = parse_type(reader, log);
|
||||
let is_reference_type = reader.peek().token_type == TokenType::Ampersand;
|
||||
if is_reference_type {
|
||||
reader.next();
|
||||
}
|
||||
let identifier = parse_identifier(reader, log, false);
|
||||
identifier.as_ref()?;
|
||||
let param_list = parse_paramlist(reader, log);
|
||||
let func_attr = parse_funcattr(reader, log);
|
||||
reader.consume(TokenType::FromKeyword, log);
|
||||
let mut source = None;
|
||||
let source_token = reader.next();
|
||||
if let TokenType::StringLiteral(s) = &source_token.token_type {
|
||||
source = Some(s.to_string());
|
||||
}
|
||||
if source.is_none() {
|
||||
log(
|
||||
Message::UnexpectedToken {
|
||||
found: source_token.token_type.clone(),
|
||||
expected: vec![TokenType::StringLiteral("".to_string())],
|
||||
},
|
||||
source_token.span,
|
||||
);
|
||||
return None;
|
||||
}
|
||||
reader.consume(TokenType::Semicolon, log);
|
||||
|
||||
Some(Box::new(ParsedStatement::ImportStatement {
|
||||
import_type: import_type.unwrap(),
|
||||
is_reference: is_reference_type,
|
||||
identifier: identifier.unwrap(),
|
||||
param_list: param_list.unwrap(),
|
||||
func_attr,
|
||||
source: source.unwrap(),
|
||||
}))
|
||||
}
|
||||
|
||||
fn parse_enum(
|
||||
_outer_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn parse_mixin(
|
||||
_outer_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
// enum ::= {'shared' | 'external'} 'enum' identifier [ ':' primtype ] (';' | ('{' identifier ['=' expr] {',' identifier ['=' expr]} '}'));
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
@ -349,6 +440,8 @@ fn parse_class(
|
|||
_outer_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
// class ::= {'shared' | 'abstract' | 'final' | 'external' | 'mixin'} 'class' identifier
|
||||
// (';' | ([':' identifier {',' identifier}] '{' {virtprop | func | var | funcdef | class} '}'));
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
@ -356,6 +449,7 @@ fn parse_funcdef(
|
|||
_outer_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
// funcdef ::= {'external' | 'shared'} 'funcdef' type ['&'] identifier paramlist ';'
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
@ -363,6 +457,7 @@ fn parse_func(
|
|||
_outer_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
// func ::= {'shared' | 'external'} ['private' | 'protected'] [((type ['&']) | '~')] identifier paramlist ['const'] funcattr (';' | statblock);
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
@ -511,17 +606,29 @@ fn parse_paramlist(
|
|||
default = parse_expr(reader, log);
|
||||
// FIXME: log if default is emtpy
|
||||
}
|
||||
params.push((param_type, type_mod, identifier, default));
|
||||
params.push((param_type.unwrap(), type_mod, identifier, default));
|
||||
}
|
||||
|
||||
return Some(Box::new(ParsedStatement::ParamList { parameters: params }));
|
||||
Some(Box::new(ParsedStatement::ParamList { parameters: params }))
|
||||
}
|
||||
|
||||
fn parse_funcattr(
|
||||
_outer_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
unimplemented!();
|
||||
reader: &mut ParseReader,
|
||||
log: &mut dyn FnMut(Message, Span),
|
||||
) -> BitFlags<FuncAttr> {
|
||||
// funcattr ::= {'override' | 'final' | 'explicit' | 'property'};
|
||||
let mut func_attr: BitFlags<FuncAttr> = BitFlags::empty();
|
||||
loop {
|
||||
match reader.peek().token_type {
|
||||
TokenType::OverrideKeyword => func_attr |= FuncAttr::Override,
|
||||
TokenType::FinalKeyword => func_attr |= FuncAttr::Final,
|
||||
TokenType::ExplicitKeyword => func_attr |= FuncAttr::Explicit,
|
||||
TokenType::PropertyKeyword => func_attr |= FuncAttr::Property,
|
||||
_ => break,
|
||||
}
|
||||
reader.next();
|
||||
}
|
||||
func_attr
|
||||
}
|
||||
|
||||
fn parse_statblock(
|
||||
|
@ -1123,6 +1230,7 @@ fn parse_lambda(
|
|||
_outer_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
// lambda ::= 'function' '(' [[type typemod] identifier {',' [type typemod] identifier}] ')' statblock;
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
@ -1262,6 +1370,7 @@ fn parse_arglist(
|
|||
_outer_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
// arglist ::= '(' [identifier ':'] assign {',' [identifier ':'] assign} ')';
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
@ -1292,6 +1401,7 @@ fn parse_initlist(
|
|||
_outer_reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
// initlist ::= '{' [assign | initlist] {',' [assign | initlist]} '}';
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
@ -1408,9 +1518,19 @@ fn parse_datatype(
|
|||
if let Some(identifier) = parse_identifier(reader, log, true) {
|
||||
return Some(Box::new(ParsedStatement::DataTypeIdentifier { identifier }));
|
||||
}
|
||||
if reader.peek().token_type == TokenType::AutoKeyword {
|
||||
reader.next();
|
||||
return Some(Box::new(ParsedStatement::DataTypeAuto {}));
|
||||
}
|
||||
parse_primtype(reader, log)
|
||||
}
|
||||
|
||||
fn parse_primtype(
|
||||
reader: &mut ParseReader,
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
let key = reader.peek();
|
||||
let res = match &key.token_type {
|
||||
TokenType::AutoKeyword => Some(Box::new(ParsedStatement::DataTypeAuto {})),
|
||||
TokenType::VoidKeyword => Some(Box::new(ParsedStatement::DataTypePrimType {
|
||||
prim_type: PrimitiveType::Void,
|
||||
})),
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
use enumflags2::bitflags;
|
||||
|
||||
#[bitflags]
|
||||
#[repr(u8)]
|
||||
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
|
||||
pub enum FuncAttr {
|
||||
Override,
|
||||
Final,
|
||||
Explicit,
|
||||
Property,
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
use super::parsed_type_modifier::ParsedTypeModifier;
|
||||
use crate::defines::{LiteralFloat, LiteralInt};
|
||||
use crate::modifiers::{FieldModifier, TypeModifier};
|
||||
use crate::parsing::parser::parsed_funcattr::FuncAttr;
|
||||
use crate::parsing::parser::parsed_type_modifier::ReferenceModifier;
|
||||
use crate::parsing::parser::parser_operators::{
|
||||
BinaryOperator, PostOperator, PreOperator, TernaryOperator,
|
||||
|
@ -175,4 +176,23 @@ pub enum ParsedStatement {
|
|||
Option<Box<ParsedStatement>>, // default expression
|
||||
)>,
|
||||
},
|
||||
InterfaceMethod {
|
||||
return_type: Box<ParsedStatement>,
|
||||
returns_reference: bool,
|
||||
identifier: String,
|
||||
param_list: Box<ParsedStatement>,
|
||||
is_const: bool,
|
||||
},
|
||||
TypeDefStatement {
|
||||
from: Box<ParsedStatement>,
|
||||
to: Box<ParsedStatement>,
|
||||
},
|
||||
ImportStatement {
|
||||
import_type: Box<ParsedStatement>,
|
||||
is_reference: bool,
|
||||
identifier: String,
|
||||
param_list: Box<ParsedStatement>,
|
||||
func_attr: BitFlags<FuncAttr>,
|
||||
source: String,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ pub enum ParsedTypeModifier {
|
|||
|
||||
#[bitflags]
|
||||
#[repr(u8)]
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
|
||||
pub enum ReferenceModifier {
|
||||
In,
|
||||
Out,
|
||||
|
|
Loading…
Reference in New Issue