Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method implementations 1: Variable references #253

Merged
merged 21 commits into from
Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions examples/class_method.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CLASS MyClass
VAR
x, y : INT;
END_VAR

METHOD testMethod
VAR_INPUT myMethodArg : INT; END_VAR
VAR myMethodLocalVar : INT; END_VAR

x := myMethodArg;
END_METHOD
END_CLASS
16 changes: 8 additions & 8 deletions examples/simple_program.st
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
TYPE the_struct : STRUCT END_STRUCT END_TYPE
PROGRAM prg
VAR
my_struct : STRUCT
END_STRUCT
END_VAR
END_PROGRAM
TYPE the_struct : STRUCT END_STRUCT END_TYPE

PROGRAM prg
VAR
my_struct : STRUCT
END_STRUCT
END_VAR
END_PROGRAM
25 changes: 23 additions & 2 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ impl Debug for Pou {
}
}

impl Pou {
pub fn get_return_name(&self) -> &str {
Pou::calc_return_name(&self.name)
}

pub fn calc_return_name(pou_name: &str) -> &str {
pou_name.split('.').last().unwrap_or_default()
}
}

#[derive(Debug, PartialEq)]
pub struct Implementation {
pub name: String,
Expand All @@ -76,14 +86,25 @@ pub enum AccessModifier {
Internal,
}

#[derive(Debug, Copy, PartialEq, Clone)]
#[derive(Debug, PartialEq, Clone)]
pub enum PouType {
Program,
Function,
FunctionBlock,
Action,
Class,
Method,
Method { owner_class: String },
}

impl PouType {
/// returns Some(owner_class) if this is a `Method` or otherwhise `None`
pub fn get_optional_owner_class(&self) -> Option<String> {
if let PouType::Method { owner_class } = self {
Some(owner_class.clone())
} else {
None
}
}
}

#[derive(Debug, PartialEq)]
Expand Down
28 changes: 20 additions & 8 deletions src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,33 @@ impl<'ink> CodeGen<'ink> {
fn generate_llvm_index(
&self,
module: &Module<'ink>,
annotations: &AnnotationMap,
global_index: &Index,
) -> Result<LlvmTypedIndex<'ink>, CompileError> {
let llvm = Llvm::new(self.context, self.context.create_builder());
let mut index = LlvmTypedIndex::new();
//Generate types index, and any global variables associated with them.
let llvm_type_index = data_type_generator::generate_data_types(&llvm, global_index)?;
let llvm_type_index =
data_type_generator::generate_data_types(&llvm, global_index, annotations)?;
index.merge(llvm_type_index);
//Generate global variables
let llvm_gv_index =
variable_generator::generate_global_variables(module, &llvm, global_index, &index)?;
let llvm_gv_index = variable_generator::generate_global_variables(
module,
&llvm,
global_index,
annotations,
&index,
)?;
index.merge(llvm_gv_index);
//Generate opaque functions for implementations and associate them with their types
let llvm = Llvm::new(self.context, self.context.create_builder());
let llvm_impl_index =
pou_generator::generate_implementation_stubs(module, llvm, global_index, &index)?;
let llvm_impl_index = pou_generator::generate_implementation_stubs(
module,
llvm,
global_index,
annotations,
&index,
)?;
index.merge(llvm_impl_index);
Ok(index)
}
Expand All @@ -94,15 +106,15 @@ impl<'ink> CodeGen<'ink> {
pub fn generate(
&self,
unit: &CompilationUnit,
_annotations: &AnnotationMap,
annotations: &AnnotationMap,
global_index: &Index,
) -> Result<String, CompileError> {
//Associate the index type with LLVM types
let llvm_index = self.generate_llvm_index(&self.module, global_index)?;
let llvm_index = self.generate_llvm_index(&self.module, annotations, global_index)?;

//generate all pous
let llvm = Llvm::new(self.context, self.context.create_builder());
let pou_generator = PouGenerator::new(llvm, global_index, &llvm_index);
let pou_generator = PouGenerator::new(llvm, global_index, annotations, &llvm_index);
//Generate the POU stubs in the first go to make sure they can be referenced.
for implementation in &unit.implementations {
//Don't generate external functions
Expand Down
Loading