Skip to content

Commit

Permalink
fix #69 (function application parsing bug) (#72)
Browse files Browse the repository at this point in the history
closes #69
  • Loading branch information
sezna authored Jun 4, 2021
1 parent 498f772 commit b5eb400
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 14 deletions.
4 changes: 3 additions & 1 deletion core_lang/src/asm_generation/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,9 @@ pub(crate) fn convert_expression_to_asm<'sc>(
TypedExpressionVariant::CodeBlock(block) => {
convert_code_block_to_asm(block, namespace, register_sequencer, Some(return_register))
}
_ => {
TypedExpressionVariant::Unit => ok(vec![], warnings, errors),
a => {
println!("unimplemented: {:?}", a);
errors.push(CompileError::Unimplemented(
"ASM generation has not yet been implemented for this.",
exp.span.clone(),
Expand Down
22 changes: 21 additions & 1 deletion core_lang/src/asm_generation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,27 @@ fn convert_node_to_asm<'sc>(
errors,
)
}
_ => {
TypedAstNodeContent::Expression(ref typed_expr) => {
let return_register = if let Some(return_register) = return_register {
return_register.clone()
} else {
register_sequencer.next()
};
let asm = type_check!(
convert_expression_to_asm(
typed_expr,
namespace,
&return_register,
register_sequencer
),
return err(warnings, errors),
warnings,
errors
);
ok(NodeAsmResult::JustAsm(asm), warnings, errors)
}
a => {
println!("Unimplemented: {:?}", a);
errors.push(CompileError::Unimplemented(
"The ASM for this construct has not been written yet.",
node.clone().span,
Expand Down
1 change: 1 addition & 0 deletions core_lang/src/control_flow_analysis/dead_code_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,7 @@ fn connect_expression<'sc>(
}
Ok(vec![asm_node])
}
Unit => Ok(vec![]),
a => {
println!("Unimplemented: {:?}", a);
return Err(CompileError::Unimplemented(
Expand Down
6 changes: 4 additions & 2 deletions core_lang/src/hll.pest
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ expr_inner = _{literal_value|if_exp|parenthesized_expression|asm_e
parenthesized_expression = {"(" ~ expr ~ ")"}
// // op exps built in to expr to prevent left recursion
expr = {expr_inner ~ (op ~ expr_inner)*}
func_app = {fn_name ~ "(" ~ (expr ~ ("," ~ expr)*)? ~ ")"}
func_app = {fn_name ~ fn_args}
fn_args = { "(" ~ (expr ~ ("," ~ expr)*)? ~ ")" }
fn_name = {var_exp}
var_exp = {unary_op? ~ var_name_ident}
method_exp = {subfield_exp ~ "(" ~ (expr ~ ("," ~ expr)*)? ~ ")"}
Expand Down Expand Up @@ -107,7 +108,8 @@ fn_decl_param = {("self")|(fn_decl_param_name ~ ":" ~ type_name)}
fn_decl_param_name = {ident}
return_type = {ident}
fn_decl_name = {ident}
type_name = {(ident ~ type_params?)|unit}
type_name = {(str_type|ident ~ type_params?)|unit}
str_type = { "str" ~ "[" ~ basic_integer ~ "]" }
trait_bounds = {"where" ~ (generic_type_param ~ ":" ~ trait_name) ~ ("," ~ generic_type_param ~ ":" ~ trait_name)*}
generic_type_param = @{ident}

Expand Down
4 changes: 2 additions & 2 deletions core_lang/src/parse_tree/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,9 @@ impl<'sc> Expression<'sc> {
func_app_parts.next().unwrap(),
return err(warnings, errors)
);
let arguments = func_app_parts.next();
let arguments = func_app_parts.next().unwrap();
let mut arguments_buf = Vec::new();
for argument in arguments {
for argument in arguments.into_inner() {
let arg = eval!(
Expression::parse_from_pair,
warnings,
Expand Down
17 changes: 10 additions & 7 deletions core_lang/src/parse_tree/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,24 +146,27 @@ impl<'sc> Literal<'sc> {
}
}
/// Converts a literal to a big-endian representation. This is padded to words.
pub(crate) fn to_bytes(&self) -> [u8; 8] {
pub(crate) fn to_bytes(&self) -> Vec<u8> {
use Literal::*;
match self {
U8(val) => [0, 0, 0, 0, 0, 0, 0, val.to_be_bytes()[0]],
U8(val) => vec![0, 0, 0, 0, 0, 0, 0, val.to_be_bytes()[0]],
U16(val) => {
let bytes = val.to_be_bytes();
[0, 0, 0, 0, 0, 0, bytes[0], bytes[1]]
vec![0, 0, 0, 0, 0, 0, bytes[0], bytes[1]]
}
U32(val) => {
let bytes = val.to_be_bytes();
[0, 0, 0, 0, bytes[0], bytes[1], bytes[2], bytes[3]]
vec![0, 0, 0, 0, bytes[0], bytes[1], bytes[2], bytes[3]]
}
U64(val) => val.to_be_bytes(),
U64(val) => val.to_be_bytes().to_vec(),
Boolean(b) => {
let bytes = (if *b { 1u64 } else { 0u64 }).to_be_bytes();
[0, 0, 0, 0, 0, 0, 0, bytes[0]]
vec![0, 0, 0, 0, 0, 0, 0, bytes[0]]
}
a => todo!("{:?}", a),
// assume utf8 for now
String(st) => st.to_string().into_bytes(),
Byte(b) => vec![0, 0, 0, 0, 0, 0, 0, b.to_be_bytes()[0]],
Byte32(b) => b.to_vec(),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion test_suite/src/e2e_vm_tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod harness;

pub fn run() {
let project_names = vec!["script_1", "script_2", "script_3"];
let project_names = vec!["script_1", "script_2", "script_3", "script_4"];
project_names.into_iter().for_each(|name| {
crate::e2e_vm_tests::harness::runs_in_vm(name);
});
Expand Down
11 changes: 11 additions & 0 deletions test_suite/src/e2e_vm_tests/test_programs/script_4/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[project]
author = "Alexander Hansen <[email protected]>"
license = "MIT"
name = "script_4"
entry = "main.sw"


[dependencies]
std = { path = "../../../../../stdlib" }


34 changes: 34 additions & 0 deletions test_suite/src/e2e_vm_tests/test_programs/script_4/src/main.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
script;
// This test tests function declarations and applications.

fn main() -> bool {
let my_struct = MyStruct { a: 5 };
let my_enum = MyEnum::Number(10);
let my_struct_with_enum = MyStructWithEnum { a: my_struct, b: my_enum };
let d = "abcde";
let e = true;
let f = 15;
let g = 0b10101010;
let h = 0b1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010;

eight_args(my_struct, my_enum, my_struct_with_enum, d, e, f, g, h);

return true;
}
struct MyStruct {
a: u64,
}

enum MyEnum {
Number: u64,
Unit: (),
}

struct MyStructWithEnum {
a: MyStruct,
b: MyEnum
}

fn eight_args(a: MyStruct, b: MyEnum, c: MyStructWithEnum, d: str[5], e: bool, f: u64, g: byte, h: byte32) {
return;
}

0 comments on commit b5eb400

Please sign in to comment.