Skip to content

Commit

Permalink
Create ADR call in parser
Browse files Browse the repository at this point in the history
  • Loading branch information
volsa committed Jun 20, 2024
1 parent 91f485f commit 963064b
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 34 deletions.
2 changes: 1 addition & 1 deletion compiler/plc_ast/src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ impl Walker for AstNode {
AstStatement::VlaRangeStatement => visitor.visit_vla_range_statement(node),
AstStatement::Assignment(stmt) => visitor.visit_assignment(stmt, node),
AstStatement::OutputAssignment(stmt) => visitor.visit_output_assignment(stmt, node),
AstStatement::ReferenceAssignment(stmt) => todo!(),
AstStatement::ReferenceAssignment(_) => todo!(),
AstStatement::CallStatement(stmt) => visitor.visit_call_statement(stmt, node),
AstStatement::ControlStatement(stmt) => visitor.visit_control_statement(stmt, node),
AstStatement::CaseCondition(stmt) => visitor.visit_case_condition(stmt, node),
Expand Down
40 changes: 20 additions & 20 deletions src/codegen/generators/statement_generator.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2020 Ghaith Hachem and Mathias Rieder
use super::{
expression_generator::{to_i1, ExpressionCodeGenerator, ExpressionValue},
expression_generator::{to_i1, ExpressionCodeGenerator},
llvm::Llvm,
};
use crate::{
Expand Down Expand Up @@ -234,25 +234,6 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
}
}

// XXX: Replace Result with CodegenResult<T>?
pub fn generate_reference_assignment_statement(
&self,
left: &AstNode,
right: &AstNode,
) -> Result<(), Diagnostic> {
let exp_gen = self.create_expr_generator();

let left_type = exp_gen.get_type_hint_info_for(left)?;
let left_pvalue: PointerValue = exp_gen.generate_expression_value(left).and_then(|it| {
it.get_basic_value_enum()
.try_into()
.map_err(|err| Diagnostic::codegen_error(format!("{err:?}").as_str(), left.get_location()))
})?;

exp_gen.generate_store(left_pvalue, left_type, right)?;
Ok(())
}

/// generates an assignment statement _left_ := _right_
///
/// `left_statement` the left side of the assignment
Expand Down Expand Up @@ -295,6 +276,25 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
Ok(())
}

// XXX: Replace Result with CodegenResult<T>?
pub fn generate_reference_assignment_statement(
&self,
left: &AstNode,
right: &AstNode,
) -> Result<(), Diagnostic> {
let exp_gen = self.create_expr_generator();

let left_type = exp_gen.get_type_hint_info_for(left)?;
let left_pvalue: PointerValue = exp_gen.generate_expression_value(left).and_then(|it| {
it.get_basic_value_enum()
.try_into()
.map_err(|err| Diagnostic::codegen_error(format!("{err:?}").as_str(), left.get_location()))
})?;

exp_gen.generate_store(left_pvalue, left_type, right)?;
Ok(())
}

fn register_debug_location(&self, statement: &AstNode) {
let line = statement.get_location().get_line_plus_one();
let column = statement.get_location().get_column();
Expand Down
6 changes: 3 additions & 3 deletions src/codegen/tests/statement_codegen_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,9 @@ fn reference_assignment() {
%b = alloca i32, align 4
store i32* null, i32** %a, align 8
store i32 0, i32* %b, align 4
%load_b = load i32, i32* %b, align 4
%0 = inttoptr i32 %load_b to i32*
store i32* %0, i32** %a, align 8
%0 = ptrtoint i32* %b to i64
%1 = inttoptr i64 %0 to i32*
store i32* %1, i32** %a, align 8
ret void
}
"###);
Expand Down
19 changes: 15 additions & 4 deletions src/parser/expressions_parser.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2020 Ghaith Hachem and Mathias Rieder

use crate::builtins::get_builtin;
use crate::{
expect_token,
lexer::Token::*,
Expand Down Expand Up @@ -223,12 +224,22 @@ fn parse_leaf_expression(lexer: &mut ParseSession) -> AstNode {
AstFactory::create_output_assignment(statement, parse_range_statement(lexer), lexer.next_id())
}
KeywordReferenceAssignment => {
debug_assert!(
get_builtin("ADR").is_some(),
"The ADR builtin must exist for the following REF= syntactic sugar"
);

lexer.advance();
AstFactory::create_reference_assignment(
statement,
parse_range_statement(lexer),
let right = parse_range_statement(lexer);
let operator =
AstFactory::create_identifier("ADR", &SourceLocation::undefined(), lexer.next_id());
let call = AstFactory::create_call_statement(
operator,
Some(right),
lexer.next_id(),
)
SourceLocation::undefined(),
);
AstFactory::create_assignment(statement, call, lexer.next_id())
}
_ => statement,
},
Expand Down
19 changes: 13 additions & 6 deletions src/parser/tests/statement_parser_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ fn reference_assignment_is_parsed() {
let result = &parse("PROGRAM main x REF= y END_PROGRAM").0.implementations[0];
insta::assert_debug_snapshot!(result.statements, @r###"
[
ReferenceAssignment {
Assignment {
left: ReferenceExpr {
kind: Member(
Identifier {
Expand All @@ -277,13 +277,20 @@ fn reference_assignment_is_parsed() {
),
base: None,
},
right: ReferenceExpr {
kind: Member(
Identifier {
name: "y",
right: CallStatement {
operator: Identifier {
name: "ADR",
},
parameters: Some(
ReferenceExpr {
kind: Member(
Identifier {
name: "y",
},
),
base: None,
},
),
base: None,
},
},
]
Expand Down

0 comments on commit 963064b

Please sign in to comment.