Skip to content

Commit f683ab5

Browse files
authored
Merge pull request #169 from ghaith/ast_files
Make the AST hold a file location
2 parents 76b1163 + 0b56ceb commit f683ab5

27 files changed

+546
-343
lines changed

src/ast.rs

+83-10
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,45 @@ impl Variable {
131131
}
132132
}
133133

134-
pub type SourceRange = core::ops::Range<usize>;
134+
#[derive(Clone, Debug, PartialEq)]
135+
pub struct SourceRange {
136+
file_path: String,
137+
range: core::ops::Range<usize>,
138+
}
139+
140+
impl SourceRange {
141+
pub fn new(file_path: &str, range: core::ops::Range<usize>) -> SourceRange {
142+
SourceRange {
143+
file_path: file_path.into(),
144+
range,
145+
}
146+
}
147+
148+
pub fn undefined() -> SourceRange {
149+
SourceRange {
150+
file_path: "".into(),
151+
range: 0..0,
152+
}
153+
}
154+
155+
pub fn get_file_path(&self) -> &str {
156+
&self.file_path
157+
}
158+
159+
pub fn get_start(&self) -> usize {
160+
self.range.start
161+
}
162+
163+
pub fn get_end(&self) -> usize {
164+
self.range.end
165+
}
166+
}
167+
168+
impl From<std::ops::Range<usize>> for SourceRange {
169+
fn from(range: std::ops::Range<usize>) -> SourceRange {
170+
SourceRange::new("", range)
171+
}
172+
}
135173

136174
#[derive(Clone, Debug, PartialEq)]
137175
pub struct NewLines {
@@ -610,25 +648,55 @@ impl Statement {
610648
Statement::LiteralArray { location, .. } => location.clone(),
611649
Statement::Reference { location, .. } => location.clone(),
612650
Statement::QualifiedReference { elements, .. } => {
613-
elements.first().map_or(0, |it| it.get_location().start)
614-
..elements.last().map_or(0, |it| it.get_location().end)
651+
let first = elements
652+
.first()
653+
.map_or_else(SourceRange::undefined, |it| it.get_location());
654+
let last = elements
655+
.last()
656+
.map_or_else(SourceRange::undefined, |it| it.get_location());
657+
SourceRange::new(first.get_file_path(), first.get_start()..last.get_end())
615658
}
616659
Statement::BinaryExpression { left, right, .. } => {
617-
left.get_location().start..right.get_location().end
660+
let left_loc = left.get_location();
661+
let right_loc = right.get_location();
662+
SourceRange::new(
663+
&left_loc.file_path,
664+
left_loc.range.start..right_loc.range.end,
665+
)
618666
}
619667
Statement::UnaryExpression { location, .. } => location.clone(),
620668
Statement::ExpressionList { expressions } => {
621-
expressions.first().map_or(0, |it| it.get_location().start)
622-
..expressions.last().map_or(0, |it| it.get_location().end)
669+
let first = expressions
670+
.first()
671+
.map_or_else(SourceRange::undefined, |it| it.get_location());
672+
let last = expressions
673+
.last()
674+
.map_or_else(SourceRange::undefined, |it| it.get_location());
675+
SourceRange::new(first.get_file_path(), first.get_start()..last.get_end())
623676
}
624677
Statement::RangeStatement { start, end } => {
625-
start.get_location().start..end.get_location().end
678+
let start_loc = start.get_location();
679+
let end_loc = end.get_location();
680+
SourceRange::new(
681+
&start_loc.file_path,
682+
start_loc.range.start..end_loc.range.end,
683+
)
626684
}
627685
Statement::Assignment { left, right } => {
628-
left.get_location().start..right.get_location().end
686+
let left_loc = left.get_location();
687+
let right_loc = right.get_location();
688+
SourceRange::new(
689+
&left_loc.file_path,
690+
left_loc.range.start..right_loc.range.end,
691+
)
629692
}
630693
Statement::OutputAssignment { left, right } => {
631-
left.get_location().start..right.get_location().end
694+
let left_loc = left.get_location();
695+
let right_loc = right.get_location();
696+
SourceRange::new(
697+
&left_loc.file_path,
698+
left_loc.range.start..right_loc.range.end,
699+
)
632700
}
633701
Statement::CallStatement { location, .. } => location.clone(),
634702
Statement::IfStatement { location, .. } => location.clone(),
@@ -637,7 +705,12 @@ impl Statement {
637705
Statement::RepeatLoopStatement { location, .. } => location.clone(),
638706
Statement::CaseStatement { location, .. } => location.clone(),
639707
Statement::ArrayAccess { reference, access } => {
640-
reference.get_location().start..access.get_location().end
708+
let reference_loc = reference.get_location();
709+
let access_loc = access.get_location();
710+
SourceRange::new(
711+
&reference_loc.file_path,
712+
reference_loc.range.start..access_loc.range.end,
713+
)
641714
}
642715
Statement::MultipliedStatement { location, .. } => location.clone(),
643716
}

src/codegen/generators/expression_generator.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright (c) 2020 Ghaith Hachem and Mathias Rieder
2-
use crate::index::Index;
2+
use crate::{ast::SourceRange, index::Index};
33
use inkwell::{
44
basic_block::BasicBlock,
55
types::BasicTypeEnum,
@@ -9,7 +9,7 @@ use inkwell::{
99
},
1010
AddressSpace, FloatPredicate, IntPredicate,
1111
};
12-
use std::{collections::HashSet, ops::Range};
12+
use std::collections::HashSet;
1313

1414
use crate::{
1515
ast::{flatten_expression_list, Dimension, Operator, Statement},
@@ -767,11 +767,13 @@ impl<'a, 'b> ExpressionCodeGenerator<'a, 'b> {
767767
let statements = access.get_as_list();
768768
if statements.is_empty() || statements.len() != dimensions.len() {
769769
return Err(CompileError::codegen_error(
770-
format!(
771-
"Mismatched array access : {} -> {} ",
772-
statements.len(),
773-
dimensions.len()
774-
),access.get_location()));
770+
format!(
771+
"Mismatched array access : {} -> {} ",
772+
statements.len(),
773+
dimensions.len()
774+
),
775+
access.get_location(),
776+
));
775777
}
776778
for (i, statement) in statements.iter().enumerate() {
777779
indices.push(self.generate_access_for_dimension(&dimensions[i], statement)?)
@@ -1109,7 +1111,7 @@ impl<'a, 'b> ExpressionCodeGenerator<'a, 'b> {
11091111
fn generate_literal_struct(
11101112
&self,
11111113
assignments: &Statement,
1112-
declaration_location: &Range<usize>,
1114+
declaration_location: &SourceRange,
11131115
) -> Result<TypeAndValue<'a>, CompileError> {
11141116
if let Some(type_info) = &self.type_hint {
11151117
if let DataTypeInformation::Struct {
@@ -1223,7 +1225,7 @@ impl<'a, 'b> ExpressionCodeGenerator<'a, 'b> {
12231225
fn generate_literal_array(
12241226
&self,
12251227
elements: &Option<Box<Statement>>,
1226-
location: &Range<usize>,
1228+
location: &SourceRange,
12271229
) -> Result<TypeAndValue<'a>, CompileError> {
12281230
if let Some(type_info) = &self.type_hint {
12291231
if let DataTypeInformation::Array {

src/codegen/generators/llvm.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,10 @@ impl<'a> Llvm<'a> {
183183

184184
Ok((data_type, BasicValueEnum::IntValue(value.unwrap())))
185185
} else {
186-
Err(CompileError::codegen_error("error expected inttype".into(),0..0))
186+
Err(CompileError::codegen_error(
187+
"error expected inttype".into(),
188+
SourceRange::undefined(),
189+
))
187190
}
188191
}
189192

@@ -206,7 +209,10 @@ impl<'a> Llvm<'a> {
206209
let data_type = index.get_type_information("REAL")?;
207210
Ok((data_type, BasicValueEnum::FloatValue(value)))
208211
} else {
209-
Err(CompileError::codegen_error("error expected floattype".into(),0..0))
212+
Err(CompileError::codegen_error(
213+
"error expected floattype".into(),
214+
SourceRange::undefined(),
215+
))
210216
}
211217
}
212218

src/codegen/generators/pou_generator.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ impl<'ink, 'cg> PouGenerator<'ink, 'cg> {
150150
&function_context,
151151
&local_index,
152152
implementation.pou_type,
153-
Some(0..0),
153+
None,
154154
)?; //TODO location
155155

156156
Ok(())
@@ -176,7 +176,10 @@ impl<'ink, 'cg> PouGenerator<'ink, 'cg> {
176176
Ok(enum_type.into_array_type().fn_type(params, false))
177177
}
178178
None => Ok(self.llvm.context.void_type().fn_type(params, false)),
179-
_ => Err(CompileError::codegen_error(format!("Unsupported return type {:?}", return_type),0..0)),
179+
_ => Err(CompileError::codegen_error(
180+
format!("Unsupported return type {:?}", return_type),
181+
SourceRange::undefined(),
182+
)),
180183
}
181184
}
182185

@@ -258,7 +261,7 @@ impl<'ink, 'cg> PouGenerator<'ink, 'cg> {
258261
PouType::Function => {
259262
let reference = Statement::Reference {
260263
name: function_context.linking_context.get_call_name().into(),
261-
location: location.unwrap_or(0usize..0usize),
264+
location: location.unwrap_or_else(SourceRange::undefined),
262265
};
263266
let mut exp_gen = ExpressionCodeGenerator::new(
264267
&self.llvm,

src/codegen/generators/statement_generator.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
use std::ops::Range;
33

44
use super::{expression_generator::ExpressionCodeGenerator, llvm::Llvm};
5-
use crate::codegen::llvm_typesystem::cast_if_needed;
65
use crate::codegen::LlvmTypedIndex;
76
use crate::typesystem::{RANGE_CHECK_LS_FN, RANGE_CHECK_LU_FN, RANGE_CHECK_S_FN, RANGE_CHECK_U_FN};
7+
use crate::{ast::SourceRange, codegen::llvm_typesystem::cast_if_needed};
88
use crate::{
99
ast::{flatten_expression_list, ConditionalBlock, Operator, Statement},
1010
compile_error::CompileError,
@@ -281,10 +281,10 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
281281

282282
/// genertes a case statement
283283
///
284-
/// CASE selector OF
285-
/// conditional_block#1:
286-
/// conditional_block#2:
287-
/// END_CASE;
284+
/// CASE selector OF
285+
/// conditional_block#1:
286+
/// conditional_block#2:
287+
/// END_CASE;
288288
///
289289
/// - `selector` the case's selector expression
290290
/// - `conditional_blocks` all case-blocks including the condition and the body
@@ -424,9 +424,9 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
424424

425425
/// generates a while statement
426426
///
427-
/// WHILE condition DO
428-
/// body
429-
/// END_WHILE
427+
/// WHILE condition DO
428+
/// body
429+
/// END_WHILE
430430
///
431431
/// - `condition` the while's condition
432432
/// - `body` the while's body statements
@@ -452,9 +452,9 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
452452
/// generates a repeat statement
453453
///
454454
///
455-
/// REPEAT
456-
/// body
457-
/// UNTIL condition END_REPEAT;
455+
/// REPEAT
456+
/// body
457+
/// UNTIL condition END_REPEAT;
458458
///
459459
/// - `condition` the repeat's condition
460460
/// - `body` the repeat's body statements
@@ -601,7 +601,7 @@ fn create_call_to_check_function_ast(
601601
check_function_name: String,
602602
parameter: Statement,
603603
sub_range: Range<Statement>,
604-
location: &Range<usize>,
604+
location: &SourceRange,
605605
) -> Statement {
606606
Statement::CallStatement {
607607
operator: Box::new(Statement::Reference {

src/codegen/llvm_index.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright (c) 2020 Ghaith Hachem and Mathias Rieder
2-
use crate::compile_error::CompileError;
2+
use crate::{ast::SourceRange, compile_error::CompileError};
33
use inkwell::types::BasicTypeEnum;
44
use inkwell::values::{BasicValueEnum, FunctionValue, GlobalValue, PointerValue};
55
use std::collections::HashMap;
@@ -99,7 +99,7 @@ impl<'ink> LlvmTypedIndex<'ink> {
9999
type_name: &str,
100100
) -> Result<BasicTypeEnum<'ink>, CompileError> {
101101
self.find_associated_type(type_name)
102-
.ok_or_else(|| CompileError::unknown_type(type_name, 0..0))
102+
.ok_or_else(|| CompileError::unknown_type(type_name, SourceRange::undefined()))
103103
}
104104

105105
pub fn find_associated_initial_value(&self, type_name: &str) -> Option<BasicValueEnum<'ink>> {

src/codegen/llvm_typesystem.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use inkwell::{
77
};
88

99
use crate::{
10+
ast::SourceRange,
1011
ast::Statement,
1112
compile_error::CompileError,
1213
index::Index,
@@ -161,13 +162,13 @@ pub fn cast_if_needed<'ctx>(
161162
let target_type = index.find_effective_type(target_type).ok_or_else(|| {
162163
CompileError::codegen_error(
163164
format!("Could not find primitive type for {:?}", target_type),
164-
0..0,
165+
SourceRange::undefined(),
165166
)
166167
})?;
167168
let value_type = index.find_effective_type(value_type).ok_or_else(|| {
168169
CompileError::codegen_error(
169170
format!("Could not find primitive type for {:?}", value_type),
170-
0..0,
171+
SourceRange::undefined(),
171172
)
172173
})?;
173174
match target_type {
@@ -322,7 +323,7 @@ pub fn get_llvm_int_type<'a>(
322323
128 => Ok(context.i128_type()),
323324
_ => Err(CompileError::codegen_error(
324325
format!("Invalid size for type : '{}' at {}", name, size),
325-
0..0,
326+
SourceRange::undefined(),
326327
)),
327328
}
328329
}
@@ -337,7 +338,7 @@ pub fn get_llvm_float_type<'a>(
337338
64 => Ok(context.f64_type()),
338339
_ => Err(CompileError::codegen_error(
339340
format!("Invalid size for type : '{}' at {}", name, size),
340-
0..0,
341+
SourceRange::undefined(),
341342
)),
342343
}
343344
}

src/codegen/tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod typesystem_test;
66
#[macro_export]
77
macro_rules! codegen_wihout_unwrap {
88
($code:tt) => {{
9-
let lexer = crate::lexer::lex($code);
9+
let lexer = crate::lexer::lex("", $code);
1010
let (mut ast, _) = crate::parser::parse(lexer).unwrap();
1111

1212
let context = inkwell::context::Context::create();
@@ -20,7 +20,7 @@ macro_rules! codegen_wihout_unwrap {
2020
#[macro_export]
2121
macro_rules! codegen {
2222
($code:tt) => {{
23-
let lexer = crate::lexer::lex($code);
23+
let lexer = crate::lexer::lex("", $code);
2424
let (mut ast, _) = crate::parser::parse(lexer).unwrap();
2525

2626
let context = inkwell::context::Context::create();

src/codegen/tests/code_gen_tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3939,7 +3939,7 @@ fn struct_initializer_needs_assignments() {
39393939
Err(CompileError::codegen_error(
39403940
"struct literal must consist of explicit assignments in the form of member := value"
39413941
.to_string(),
3942-
185..186
3942+
(185..186).into()
39433943
))
39443944
);
39453945
assert_eq!(source[185..186].to_string(), "2".to_string());

0 commit comments

Comments
 (0)