Skip to content

Commit f9b9dc4

Browse files
committed
Review comments
The builtinin index is now created first in the lib, and not always by visiting an ast. Also fixed the index import to use not skip enum and hardware constants. As a side effect of the index being imported, some index numbers changed in some tests
1 parent cfc603f commit f9b9dc4

10 files changed

+133
-89
lines changed

src/builtins.rs

+3-15
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

+7-5
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
}

src/index.rs

+60-30
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,41 @@ 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

450-
//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);
454-
self.enum_global_variables.insert(name, e.clone());
455-
self.enum_qualified_variables
456-
.insert(e.qualified_name.to_lowercase(), e);
443+
//enmu_variables use the qualified variables since name conflicts will be overriden in the enum_global
444+
for (qualified_name, e) in other.enum_qualified_variables.drain(..) {
445+
let e = self.transfer_constants(e, &mut other.constant_expressions);
446+
dbg!(&e);
447+
self.enum_global_variables
448+
.insert(e.get_name().to_lowercase(), e.clone());
449+
self.enum_qualified_variables.insert(qualified_name, e);
457450
}
458451

459452
//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);
453+
for (name, e) in other.global_initializers.drain(..) {
454+
let e = self.transfer_constants(e, &mut other.constant_expressions);
463455
self.global_initializers.insert(name, e);
464456
}
465457

466458
//member variables
467459
for (name, mut members) in other.member_variables.drain(..) {
468460
//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);
461+
let mut new_members = IndexMap::default();
462+
for (name, e) in members.drain(..) {
463+
let e = self.transfer_constants(e, &mut other.constant_expressions);
464+
new_members.insert(name, e);
472465
}
473-
self.member_variables.insert(name, members);
466+
self.member_variables.insert(name, new_members);
474467
}
475468

476469
//types
477470
for (name, mut e) in other.type_index.types.drain(..) {
478471
e.initial_value =
479472
self.maybe_import_const_expr(&mut other.constant_expressions, &e.initial_value);
480-
481473
match &mut e.information {
482474
//import constant expressions in array-type-definitions
483475
DataTypeInformation::Array { dimensions, .. } => {
@@ -511,6 +503,38 @@ impl Index {
511503
// self.constant_expressions.import(other.constant_expressions)
512504
}
513505

506+
fn transfer_constants(
507+
&mut self,
508+
mut variable: VariableIndexEntry,
509+
import_from: &mut ConstExpressions,
510+
) -> VariableIndexEntry {
511+
variable.initial_value = self.maybe_import_const_expr(import_from, &variable.initial_value);
512+
513+
let binding = if let Some(HardwareBinding {
514+
direction,
515+
access,
516+
entries,
517+
location,
518+
}) = variable.get_hardware_binding()
519+
{
520+
let mut new_entries = vec![];
521+
for entry in entries {
522+
if let Some(e) = self.maybe_import_const_expr(import_from, &Some(*entry)) {
523+
new_entries.push(e);
524+
}
525+
}
526+
Some(HardwareBinding {
527+
direction: *direction,
528+
access: *access,
529+
entries: new_entries,
530+
location: location.clone(),
531+
})
532+
} else {
533+
None
534+
};
535+
variable.set_hardware_binding(binding)
536+
}
537+
514538
/// imports the corresponding const-expression (according to the given initializer-id) from the given ConstExpressions
515539
/// into self's const-expressions and returns the new Id
516540
fn maybe_import_const_expr(
@@ -520,7 +544,7 @@ impl Index {
520544
) -> Option<ConstId> {
521545
initializer_id
522546
.as_ref()
523-
.and_then(|it| import_from.remove(it))
547+
.and_then(|it| import_from.clone(it))
524548
.map(|(init, target_type, scope)| {
525549
self.get_mut_const_expressions()
526550
.add_constant_expression(init, target_type, scope)
@@ -540,7 +564,7 @@ impl Index {
540564
let ts = match type_size {
541565
TypeSize::LiteralInteger(_) => Some(*type_size),
542566
TypeSize::ConstExpression(id) => import_from
543-
.remove(id)
567+
.clone(id)
544568
.map(|(expr, target_type, scope)| {
545569
self.get_mut_const_expressions().add_constant_expression(
546570
expr,
@@ -970,11 +994,17 @@ impl Index {
970994
InstanceIterator::with_filter(self, inner_filter)
971995
}
972996

973-
pub fn is_builtin(&self, function: &str) -> bool {
997+
/// If the provided name is a builtin function, returns it from the builtin index
998+
pub fn get_builtin_function(&self, name: &str) -> Option<&'_ BuiltIn> {
974999
//Find a type for that function, see if that type is builtin
975-
self.find_effective_type_info(function)
1000+
if let Some(true) = self
1001+
.find_effective_type_info(name)
9761002
.map(DataTypeInformation::is_builtin)
977-
.unwrap_or_default()
1003+
{
1004+
builtins::get_builtin(name)
1005+
} else {
1006+
None
1007+
}
9781008
}
9791009
}
9801010

src/index/const_expressions.rs

+22-7
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

+6-3
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

+6-6
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

+2-7
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

+5
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)