Skip to content

Commit 50c2874

Browse files
committed
wip
1 parent cfc603f commit 50c2874

13 files changed

+161
-85
lines changed

src/builtins.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,7 @@ pub fn parse_built_ins(id_provider: IdProvider) -> (CompilationUnit, Vec<Diagnos
9292
parser::parse(lexer::lex_with_ids(&src, id_provider), LinkageType::BuiltIn)
9393
}
9494

95-
pub fn generate<'ink, 'b>(
96-
builtin: &str,
97-
generator: &'b ExpressionCodeGenerator<'ink, 'b>,
98-
params: Vec<&AstStatement>,
99-
source_location: SourceRange,
100-
) -> Result<BasicValueEnum<'ink>, Diagnostic> {
101-
BUILTIN
102-
.get(builtin.to_uppercase().as_str())
103-
.ok_or_else(|| {
104-
Diagnostic::codegen_error(
105-
&format!("Cannot find builtin function {}", builtin),
106-
source_location.clone(),
107-
)
108-
})
109-
.and_then(|it| it.codegen(generator, params.as_slice(), source_location))
95+
/// Returns the requested functio from the builtin index or None
96+
pub fn get_builtin(name: &str) -> Option<&'static BuiltIn> {
97+
BUILTIN.get(name.to_uppercase().as_str())
11098
}

src/codegen/generators/expression_generator.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) 2020 Ghaith Hachem and Mathias Rieder
22
use crate::{
33
ast::{self, DirectAccessType, SourceRange},
4-
builtins,
54
codegen::llvm_typesystem,
65
diagnostics::{Diagnostic, INTERNAL_LLVM_ERROR},
76
index::{ImplementationIndexEntry, ImplementationType, Index, VariableIndexEntry},
@@ -451,14 +450,17 @@ impl<'a, 'b> ExpressionCodeGenerator<'a, 'b> {
451450
})?;
452451

453452
//If the function is builtin, generate a basic value enum for it
454-
if self.index.is_builtin(implementation.get_call_name()) {
455-
return builtins::generate(
456-
implementation.get_call_name(),
453+
if let Some(builtin) = self
454+
.index
455+
.get_builtin_function(implementation.get_call_name())
456+
{
457+
return builtin.codegen(
457458
self,
458459
parameters
459460
.as_ref()
460461
.map(|it| ast::flatten_expression_list(it))
461-
.unwrap_or_default(),
462+
.unwrap_or_default()
463+
.as_slice(),
462464
operator.get_location(),
463465
);
464466
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
source: src/codegen/tests/code_gen_tests.rs
3+
assertion_line: 2052
4+
expression: result
5+
6+
---
7+
; ModuleID = 'main'
8+
source_filename = "main"
9+
10+
@x = global i8 0
11+
@y = global i16 0
12+
@z = global i32 0
13+
@red = unnamed_addr constant i32 0
14+
@yellow = unnamed_addr constant i32 1
15+
@green = unnamed_addr constant i32 2
16+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
source: src/codegen/tests/code_gen_tests.rs
3+
assertion_line: 2076
4+
expression: result
5+
6+
---
7+
; ModuleID = 'main'
8+
source_filename = "main"
9+
10+
@x = global i8 0
11+
@y = global i16 0
12+
@z = global i32 0
13+
@red = unnamed_addr constant i32 22
14+
@yellow = unnamed_addr constant i32 33
15+
@green = unnamed_addr constant i32 44
16+

src/index.rs

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ use crate::{
66
AstStatement, DirectAccessType, HardwareAccessType, Implementation, LinkageType, PouType,
77
SourceRange, TypeNature,
88
},
9-
builtins,
9+
builtins::{self, BuiltIn},
1010
diagnostics::Diagnostic,
11-
lexer::IdProvider,
1211
typesystem::{self, *},
1312
};
1413

@@ -428,11 +427,6 @@ pub struct Index {
428427
}
429428

430429
impl Index {
431-
pub fn create_with_builtins(id_provider: IdProvider) -> Index {
432-
let (unit, _) = builtins::parse_built_ins(id_provider.clone());
433-
visitor::visit_index(Index::default(), &unit, id_provider)
434-
}
435-
436430
/// imports all entries from the given index into the current index
437431
///
438432
/// imports all global_variables, member_variables, types and implementations
@@ -441,43 +435,40 @@ impl Index {
441435
/// into the current one
442436
pub fn import(&mut self, mut other: Index) {
443437
//global variables
444-
for (name, mut e) in other.global_variables.drain(..) {
445-
e.initial_value =
446-
self.maybe_import_const_expr(&mut other.constant_expressions, &e.initial_value);
438+
for (name, e) in other.global_variables.drain(..) {
439+
let e = self.transfer_constants(e, &mut other.constant_expressions);
447440
self.global_variables.insert(name, e);
448441
}
449442

450443
//enum_global_variables
451-
for (name, mut e) in other.enum_global_variables.drain(..) {
452-
e.initial_value =
453-
self.maybe_import_const_expr(&mut other.constant_expressions, &e.initial_value);
444+
for (name, e) in other.enum_global_variables.drain(..) {
445+
let e = self.transfer_constants(e, &mut other.constant_expressions);
454446
self.enum_global_variables.insert(name, e.clone());
455447
self.enum_qualified_variables
456448
.insert(e.qualified_name.to_lowercase(), e);
457449
}
458450

459451
//initializers
460-
for (name, mut e) in other.global_initializers.drain(..) {
461-
e.initial_value =
462-
self.maybe_import_const_expr(&mut other.constant_expressions, &e.initial_value);
452+
for (name, e) in other.global_initializers.drain(..) {
453+
let e = self.transfer_constants(e, &mut other.constant_expressions);
463454
self.global_initializers.insert(name, e);
464455
}
465456

466457
//member variables
467458
for (name, mut members) in other.member_variables.drain(..) {
468459
//enum qualified variables
469-
for (_, mut e) in members.iter_mut() {
470-
e.initial_value =
471-
self.maybe_import_const_expr(&mut other.constant_expressions, &e.initial_value);
460+
let mut new_members = IndexMap::default();
461+
for (name, e) in members.drain(..) {
462+
let e = self.transfer_constants(e, &mut other.constant_expressions);
463+
new_members.insert(name, e);
472464
}
473-
self.member_variables.insert(name, members);
465+
self.member_variables.insert(name, new_members);
474466
}
475467

476468
//types
477469
for (name, mut e) in other.type_index.types.drain(..) {
478470
e.initial_value =
479471
self.maybe_import_const_expr(&mut other.constant_expressions, &e.initial_value);
480-
481472
match &mut e.information {
482473
//import constant expressions in array-type-definitions
483474
DataTypeInformation::Array { dimensions, .. } => {
@@ -511,6 +502,38 @@ impl Index {
511502
// self.constant_expressions.import(other.constant_expressions)
512503
}
513504

505+
fn transfer_constants(
506+
&mut self,
507+
mut variable: VariableIndexEntry,
508+
import_from: &mut ConstExpressions,
509+
) -> VariableIndexEntry {
510+
variable.initial_value = self.maybe_import_const_expr(import_from, &variable.initial_value);
511+
512+
let binding = if let Some(HardwareBinding {
513+
direction,
514+
access,
515+
entries,
516+
location,
517+
}) = variable.get_hardware_binding()
518+
{
519+
let mut new_entries = vec![];
520+
for entry in entries {
521+
if let Some(e) = self.maybe_import_const_expr(import_from, &Some(*entry)) {
522+
new_entries.push(e);
523+
}
524+
}
525+
Some(HardwareBinding {
526+
direction: *direction,
527+
access: *access,
528+
entries: new_entries,
529+
location: location.clone(),
530+
})
531+
} else {
532+
None
533+
};
534+
variable.set_hardware_binding(binding)
535+
}
536+
514537
/// imports the corresponding const-expression (according to the given initializer-id) from the given ConstExpressions
515538
/// into self's const-expressions and returns the new Id
516539
fn maybe_import_const_expr(
@@ -520,7 +543,7 @@ impl Index {
520543
) -> Option<ConstId> {
521544
initializer_id
522545
.as_ref()
523-
.and_then(|it| import_from.remove(it))
546+
.and_then(|it| import_from.clone(it))
524547
.map(|(init, target_type, scope)| {
525548
self.get_mut_const_expressions()
526549
.add_constant_expression(init, target_type, scope)
@@ -540,7 +563,7 @@ impl Index {
540563
let ts = match type_size {
541564
TypeSize::LiteralInteger(_) => Some(*type_size),
542565
TypeSize::ConstExpression(id) => import_from
543-
.remove(id)
566+
.clone(id)
544567
.map(|(expr, target_type, scope)| {
545568
self.get_mut_const_expressions().add_constant_expression(
546569
expr,
@@ -970,11 +993,17 @@ impl Index {
970993
InstanceIterator::with_filter(self, inner_filter)
971994
}
972995

973-
pub fn is_builtin(&self, function: &str) -> bool {
996+
/// If the provided name is a builtin function, returns it from the builtin index
997+
pub fn get_builtin_function(&self, name: &str) -> Option<&'_ BuiltIn> {
974998
//Find a type for that function, see if that type is builtin
975-
self.find_effective_type_info(function)
999+
if let Some(true) = self
1000+
.find_effective_type_info(name)
9761001
.map(DataTypeInformation::is_builtin)
977-
.unwrap_or_default()
1002+
{
1003+
builtins::get_builtin(name)
1004+
} else {
1005+
None
1006+
}
9781007
}
9791008
}
9801009

src/index/const_expressions.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,29 @@ impl ConstExpressions {
115115
self.expressions.get(*id).map(|it| &it.expr)
116116
}
117117

118-
/// removes the expression from the ConstExpressions and returns all of its elements
119-
pub fn remove(&mut self, id: &ConstId) -> Option<(AstStatement, String, Option<String>)> {
120-
self.expressions.remove(*id).map(|it| match it.expr {
121-
ConstExpression::Unresolved { statement, scope } => {
122-
(statement, it.target_type_name, scope)
118+
// /// removes the expression from the ConstExpressions and returns all of its elements
119+
// pub fn remove(&mut self, id: &ConstId) -> Option<(AstStatement, String, Option<String>)> {
120+
// self.expressions.remove(*id).map(|it| match it.expr {
121+
// ConstExpression::Unresolved { statement, scope } => {
122+
// (statement, it.target_type_name, scope)
123+
// }
124+
// ConstExpression::Resolved(s) => (s, it.target_type_name, None),
125+
// ConstExpression::Unresolvable { statement: s, .. } => (s, it.target_type_name, None),
126+
// })
127+
// }
128+
129+
/// clones the expression in the ConstExpressions and returns all of its elements
130+
pub fn clone(&self, id: &ConstId) -> Option<(AstStatement, String, Option<String>)> {
131+
self.expressions.get(*id).map(|it| match &it.expr {
132+
ConstExpression::Unresolved { statement, scope } => (
133+
statement.clone(),
134+
it.target_type_name.clone(),
135+
scope.clone(),
136+
),
137+
ConstExpression::Resolved(s) => (s.clone(), it.target_type_name.clone(), None),
138+
ConstExpression::Unresolvable { statement: s, .. } => {
139+
(s.clone(), it.target_type_name.clone(), None)
123140
}
124-
ConstExpression::Resolved(s) => (s, it.target_type_name, None),
125-
ConstExpression::Unresolvable { statement: s, .. } => (s, it.target_type_name, None),
126141
})
127142
}
128143

src/index/tests/builtin_tests.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
use crate::{index::Index, lexer::IdProvider, test_utils::tests::index};
1+
use crate::{builtins, lexer::IdProvider, test_utils::tests::index};
22

33
#[test]
44
fn builtin_functions_added_to_index() {
5-
let index = Index::create_with_builtins(IdProvider::default());
5+
let provider = IdProvider::default();
6+
let (builtins, _) = builtins::parse_built_ins(provider.clone());
7+
let index = crate::index::visitor::visit(&builtins, provider);
8+
69
assert!(index.find_member("ADR", "in").is_some());
710
assert!(index.find_member("REF", "in").is_some());
811
assert!(index.find_implementation("ADR").is_some());
912
assert!(index.find_implementation("REF").is_some());
1013
}
1114

1215
#[test]
13-
fn default_visitor_creates_builtins() {
16+
fn test_indexer_has_builtins() {
1417
let (_, index) = index("");
1518
assert!(index.find_member("ADR", "in").is_some());
1619
assert!(index.find_member("REF", "in").is_some());

src/index/tests/snapshots/rusty__index__tests__instance_resolver_tests__array_with_const_instances_are_repeated.snap

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: src/index/tests/instance_resolver_tests.rs
3-
assertion_line: 169
3+
assertion_line: 170
44
expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
55

66
---
@@ -44,7 +44,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
4444
qualified_name: "MainProg.size",
4545
initial_value: Some(
4646
Index {
47-
index: 2,
47+
index: 0,
4848
generation: 0,
4949
},
5050
),
@@ -99,13 +99,13 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
9999
Dimension {
100100
start_offset: ConstExpression(
101101
Index {
102-
index: 0,
102+
index: 1,
103103
generation: 0,
104104
},
105105
),
106106
end_offset: ConstExpression(
107107
Index {
108-
index: 1,
108+
index: 2,
109109
generation: 0,
110110
},
111111
),
@@ -146,13 +146,13 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
146146
Dimension {
147147
start_offset: ConstExpression(
148148
Index {
149-
index: 0,
149+
index: 1,
150150
generation: 0,
151151
},
152152
),
153153
end_offset: ConstExpression(
154154
Index {
155-
index: 1,
155+
index: 2,
156156
generation: 0,
157157
},
158158
),

src/index/visitor.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use crate::index::{Index, MemberInfo};
99
use crate::lexer::IdProvider;
1010
use crate::typesystem::{self, *};
1111

12-
pub fn visit_index(mut index: Index, unit: &CompilationUnit, mut id_provider: IdProvider) -> Index {
12+
pub fn visit(unit: &CompilationUnit, mut id_provider: IdProvider) -> Index {
13+
let mut index = Index::default();
1314
//Create the typesystem
1415
let builtins = get_builtin_types();
1516
for data_type in builtins {
@@ -37,12 +38,6 @@ pub fn visit_index(mut index: Index, unit: &CompilationUnit, mut id_provider: Id
3738
index
3839
}
3940

40-
/// Visits the ast, creating an index of the content. Appends builtin functions to that index
41-
pub fn visit(unit: &CompilationUnit, id_provider: IdProvider) -> Index {
42-
let index = Index::create_with_builtins(id_provider.clone());
43-
visit_index(index, unit, id_provider)
44-
}
45-
4641
pub fn visit_pou(index: &mut Index, pou: &Pou) {
4742
let interface_name = format!("{}_interface", &pou.name);
4843

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,13 @@ fn parse_and_index<T: SourceContainer>(
440440
linkage: LinkageType,
441441
) -> Result<(Index, Units), Diagnostic> {
442442
let mut index = Index::default();
443+
443444
let mut units = Vec::new();
444445

446+
//parse the builtins into the index
447+
let (builtins, _) = builtins::parse_built_ins(id_provider.clone());
448+
index.import(index::visitor::visit(&builtins, id_provider.clone()));
449+
445450
for container in source {
446451
let location: String = container.get_location().into();
447452
let e = container

0 commit comments

Comments
 (0)