Support constructor func calls, more integration tests

This commit is contained in:
Deukhoofd 2022-04-07 20:48:38 +02:00
parent 69b5d76a9b
commit 08eb97cf38
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
12 changed files with 135 additions and 17 deletions

View File

@ -24,4 +24,4 @@ debug = true
opt-level = 3
[profile.dev]
opt-level = 1
opt-level = 0

View File

@ -20,7 +20,7 @@ fn integration_add_function() {
return a + b;
}";
let lexed_tokens = lex(script, &mut panic_on_error);
println!("{}", serde_json::to_string(&lexed_tokens).unwrap());
println!("Lexed tokens JSON: {}", serde_json::to_string(&lexed_tokens).unwrap());
let expected_tokens: Vec<LexToken> =
serde_json::from_str(r#"[
{
@ -254,7 +254,7 @@ fn integration_add_function() {
assert_eq!(lexed_tokens, expected_tokens);
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
println!("{}", serde_json::to_string(&parsed_tree).unwrap());
println!("Parsed Tree JSON: {}", serde_json::to_string(&parsed_tree).unwrap());
let expected_tree: Box<ParsedStatement> =
serde_json::from_str(r#"{
"Script": {
@ -264,6 +264,7 @@ fn integration_add_function() {
"modifiers": 0,
"field_mod": null,
"is_destructor": false,
"is_constructor": false,
"returns_reference": false,
"return_type": {
"Type": {

View File

@ -68,7 +68,7 @@ fn panic_on_error(msg: Message, _: Span) {{
fn integration_{name}() {{
let script = "{script}";
let lexed_tokens = lex(script, &mut panic_on_error);
println!("{{}}", serde_json::to_string(&lexed_tokens).unwrap());
println!("Lexed tokens JSON: {{}}", serde_json::to_string(&lexed_tokens).unwrap());
"#,
name = test_name,
script = script.as_str()
@ -94,7 +94,7 @@ fn integration_{name}() {{
testfile,
r##"
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
println!("{{}}", serde_json::to_string(&parsed_tree).unwrap());
println!("Parsed Tree JSON: {{}}", serde_json::to_string(&parsed_tree).unwrap());
"##
)
.unwrap();

View File

@ -0,0 +1,77 @@
////////////////////////////
// Automatically Generated//
////////////////////////////
use crate::logger::messages::Message;
use crate::parsing::lexer::lex;
use crate::parsing::lexer::lex_tokens::LexToken;
use crate::parsing::parser::parse;
use crate::parsing::parser::parsed_statement::ParsedStatement;
use crate::span::Span;
fn ignore_error(_msg: Message, _: Span) {
}
fn panic_on_error(msg: Message, _: Span) {
std::panic::panic_any(msg.stringify());
}
#[test]
fn integration_class_with_many_statements() {
let script = "final shared class Foobar {
int _a;
int _b;
Foobar(int a, int b) {
_a = a;
_b = b;
}
int GetA(){
return _a;
}
int Add() {
return _a + _b;
}
class Inner {
int a;
}
}";
let lexed_tokens = lex(script, &mut panic_on_error);
println!("Lexed tokens JSON: {}", serde_json::to_string(&lexed_tokens).unwrap());
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
println!("Parsed Tree JSON: {}", serde_json::to_string(&parsed_tree).unwrap());
}
// A substring of a script should never panic, even though it might be completely invalid.
#[test]
fn integration_class_with_many_statements_substring() {
let mut script = "final shared class Foobar {
int _a;
int _b;
Foobar(int a, int b) {
_a = a;
_b = b;
}
int GetA(){
return _a;
}
int Add() {
return _a + _b;
}
class Inner {
int a;
}
}".to_string();
for _ in 0..script.len() {
script.pop();
let lexed_tokens = lex(script.as_str(), &mut ignore_error);
let _parsed_tree = parse(lexed_tokens, &mut ignore_error);
}
}

View File

@ -18,7 +18,7 @@ fn panic_on_error(msg: Message, _: Span) {
fn integration_empty_class_declaration() {
let script = "class Foo {}";
let lexed_tokens = lex(script, &mut panic_on_error);
println!("{}", serde_json::to_string(&lexed_tokens).unwrap());
println!("Lexed tokens JSON: {}", serde_json::to_string(&lexed_tokens).unwrap());
let expected_tokens: Vec<LexToken> =
serde_json::from_str(r#"[
{
@ -76,7 +76,7 @@ fn integration_empty_class_declaration() {
assert_eq!(lexed_tokens, expected_tokens);
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
println!("{}", serde_json::to_string(&parsed_tree).unwrap());
println!("Parsed Tree JSON: {}", serde_json::to_string(&parsed_tree).unwrap());
let expected_tree: Box<ParsedStatement> =
serde_json::from_str(r#"{
"Script": {

View File

@ -24,7 +24,7 @@ fn integration_enum_definition() {
e
}";
let lexed_tokens = lex(script, &mut panic_on_error);
println!("{}", serde_json::to_string(&lexed_tokens).unwrap());
println!("Lexed tokens JSON: {}", serde_json::to_string(&lexed_tokens).unwrap());
let expected_tokens: Vec<LexToken> =
serde_json::from_str(r#"[
{
@ -395,7 +395,7 @@ fn integration_enum_definition() {
assert_eq!(lexed_tokens, expected_tokens);
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
println!("{}", serde_json::to_string(&parsed_tree).unwrap());
println!("Parsed Tree JSON: {}", serde_json::to_string(&parsed_tree).unwrap());
let expected_tree: Box<ParsedStatement> =
serde_json::from_str(r#"{
"Script": {

View File

@ -3,4 +3,5 @@
////////////////////////////mod enum_definition;
mod multiple_inheritance_class;
mod empty_class_declaration;
mod class_with_many_statements;
mod add_function;

View File

@ -18,7 +18,7 @@ fn panic_on_error(msg: Message, _: Span) {
fn integration_multiple_inheritance_class() {
let script = "class Foo : Zom, Aar, Bar {}";
let lexed_tokens = lex(script, &mut panic_on_error);
println!("{}", serde_json::to_string(&lexed_tokens).unwrap());
println!("Lexed tokens JSON: {}", serde_json::to_string(&lexed_tokens).unwrap());
let expected_tokens: Vec<LexToken> =
serde_json::from_str(r#"[
{
@ -152,7 +152,7 @@ fn integration_multiple_inheritance_class() {
assert_eq!(lexed_tokens, expected_tokens);
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
println!("{}", serde_json::to_string(&parsed_tree).unwrap());
println!("Parsed Tree JSON: {}", serde_json::to_string(&parsed_tree).unwrap());
let expected_tree: Box<ParsedStatement> =
serde_json::from_str(r#"{
"Script": {

View File

@ -6,6 +6,7 @@
"modifiers": 0,
"field_mod": null,
"is_destructor": false,
"is_constructor": false,
"returns_reference": false,
"return_type": {
"Type": {

View File

@ -0,0 +1,21 @@
final shared class Foobar {
int _a;
int _b;
Foobar(int a, int b) {
_a = a;
_b = b;
}
int GetA(){
return _a;
}
int Add() {
return _a + _b;
}
class Inner {
int a;
}
}

View File

@ -736,8 +736,20 @@ fn parse_func(
returns_reference = true;
reader.next();
}
return_type.as_ref()?;
}
let name = parse_identifier(&mut reader, log, true);
let mut name = parse_identifier(&mut reader, log, true);
let mut is_constructor = false;
if name.is_none() && return_type.is_some() {
if let ParsedStatement::Type { datatype, .. } = return_type.as_ref().unwrap().as_ref() {
if let ParsedStatement::DataTypeIdentifier { identifier } = datatype.as_ref() {
name = Some(identifier.to_string());
is_constructor = true;
}
}
}
name.as_ref()?;
let param_list = parse_paramlist(&mut reader, log);
param_list.as_ref()?;
@ -759,6 +771,7 @@ fn parse_func(
modifiers,
field_mod,
is_destructor,
is_constructor,
returns_reference,
return_type,
name: name.unwrap(),
@ -773,6 +786,7 @@ fn parse_virtprop(
outer_reader: &mut ParseReader,
log: &mut dyn FnMut(Message, Span),
) -> Option<Box<ParsedStatement>> {
// virtprop ::= ['private' | 'protected'] type ['&'] identifier '{' {('get' | 'set') ['const'] funcattr (statblock | ';')} '}';
let mut reader = outer_reader.create_inner();
let mut field_mod: Option<FieldModifier> = None;
match reader.peek().token_type {
@ -794,7 +808,7 @@ fn parse_virtprop(
reader.next();
is_handle = true;
}
let identifier = parse_identifier(&mut reader, log, false);
let identifier = parse_identifier(&mut reader, log, true);
identifier.as_ref()?;
let next = reader.next();
if next.token_type != TokenType::OpenCurlyBracket {
@ -1015,7 +1029,7 @@ fn parse_var(
}
property_type.as_ref()?;
let identifier = parse_identifier(&mut reader, log, false);
let identifier = parse_identifier(&mut reader, log, true);
identifier.as_ref()?;
let mut assignment: Option<Box<ParsedStatement>> = None;
@ -1402,7 +1416,6 @@ fn parse_exprterm(
})
}
println!("{:?}", real_value);
outer_reader.set_from_inner(&reader);
Some(real_value)
}
@ -1567,7 +1580,7 @@ fn parse_exprvalue(
fn parse_lambda(
reader: &mut ParseReader,
log: &mut dyn FnMut(Message, Span),
_log: &mut dyn FnMut(Message, Span),
) -> Option<Box<ParsedStatement>> {
// lambda ::= 'function' '(' [[type typemod] identifier {',' [type typemod] identifier}] ')' statblock;
if reader.peek().token_type != TokenType::FunctionKeyword {
@ -1783,7 +1796,10 @@ fn parse_assign(
ternary.as_ref()?;
if let Some(assign_op) = parse_assignop(reader, log) {
let assign = parse_assign(reader, log);
// FIXME: deal with None assign.
if assign.is_none() {
// FIXME: Logging
return Some(Box::new(ParsedStatement::Invalid));
}
return Some(Box::new(ParsedStatement::Assignment {
left: ternary.unwrap(),
operator: assign_op,

View File

@ -216,6 +216,7 @@ pub enum ParsedStatement {
modifiers: BitFlags<TypeModifier>,
field_mod: Option<FieldModifier>,
is_destructor: bool,
is_constructor: bool,
returns_reference: bool,
return_type: Option<Box<ParsedStatement>>,
name: String,