Skip to content

Commit 2764dbf

Browse files
authored
Merge pull request #76 from Quickfall/feat/type-utils
[feat] Type utils
2 parents e96855d + f2c92dd commit 2764dbf

31 files changed

Lines changed: 436 additions & 63 deletions

File tree

compiler/ast/src/tree.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ pub enum ASTTreeNodeKind {
3131

3232
ThisStructParam,
3333

34+
UnwrapCondition { original: Box<ASTTreeNode>, target_type: ASTType, unsafe_unwrap: bool, target_var: Option<HashedString> },
35+
UnwrapValue { original: Box<ASTTreeNode>, target_type: ASTType, unsafe_unwrap: bool },
36+
3437
OperatorBasedConditionMember { lval: Box<ASTTreeNode>, rval: Box<ASTTreeNode>, operator: ComparingOperator },
3538
BooleanBasedConditionMember { val: Box<ASTTreeNode>, negate: bool },
3639

@@ -156,6 +159,7 @@ impl Display for ASTTreeNode {
156159
impl Display for ASTTreeNodeKind {
157160
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
158161
let s = match self {
162+
Self::UnwrapCondition { .. } | Self::UnwrapValue { .. } => "unwrap",
159163
Self::IntegerLit { .. } => "integer literal",
160164
Self::StringLit(_) => "string literal",
161165
Self::ThisStructParam => "this reference",

compiler/ast/src/types.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ pub enum ASTType {
1818
/// 0: The raw type name
1919
/// 1: The type parameters
2020
/// 2: The size specifiers
21-
Generic(String, Vec<Box<ASTType>>, Vec<usize>), // Potential lowering to base-sized
21+
/// 3: enum specifier
22+
Generic(String, Vec<Box<ASTType>>, Vec<usize>, Option<String>), // Potential lowering to base-sized
2223

2324
/// A pointer type node. Represents a pointer version
2425
/// 0: Is the pointer a poiner of arrays
@@ -36,7 +37,7 @@ pub enum ASTType {
3637
impl ASTType {
3738
pub fn get_generic_name(&self) -> String {
3839
match self {
39-
Self::Generic(s, _, _) => s.clone(),
40+
Self::Generic(s, _, _, _) => s.clone(),
4041
Self::Pointer(_, inner) => inner.get_generic_name(),
4142
Self::Reference(inner) => inner.get_generic_name(),
4243
Self::Array(_, inner) => inner.get_generic_name()

compiler/ast_parser/src/control/if_else.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ use lexer::token::{LexerToken, LexerTokenType};
77

88
use ast::{tree::{ASTTreeNode, ASTTreeNodeKind}};
99

10-
use crate::{functions::parse_node_body, value::parse_ast_value};
10+
use crate::{functions::parse_node_body, value::{parse_ast_condition_if_statement_value}};
1111

1212
pub fn parse_condition_member(tokens: &Vec<LexerToken>, ind: &mut usize) -> DiagnosticResult<Box<ASTTreeNode>> {
1313
tokens[*ind].expects(LexerTokenType::ParenOpen)?;
1414

1515
*ind += 1;
16-
let cond = parse_ast_value(tokens, ind)?;
16+
let cond = parse_ast_condition_if_statement_value(tokens, ind)?;
1717

1818
tokens[*ind].expects(LexerTokenType::ParenClose)?;
1919

compiler/ast_parser/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub mod control;
1818
pub mod variables;
1919
pub mod types;
2020
pub mod arrays;
21+
pub mod unwraps;
2122

2223
pub fn parse_ast_ctx(tokens: &Vec<LexerToken>) -> DiagnosticResult<ParserCtx> {
2324
let mut ind = 0;

compiler/ast_parser/src/structs/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub fn parse_type_declaration(tokens: &Vec<LexerToken>, ind: &mut usize, layout:
2626

2727
let mut members: Vec<Box<ASTTreeNode>> = Vec::new();
2828

29-
let temp_type = ASTType::Generic(type_name.0.clone(), vec![], vec![]);
29+
let temp_type = ASTType::Generic(type_name.0.clone(), vec![], vec![], None);
3030

3131
while tokens[*ind].tok_type != LexerTokenType::BracketClose {
3232
if tokens[*ind].tok_type == LexerTokenType::Function {

compiler/ast_parser/src/types.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use lexer::{token::{LexerToken, LexerTokenType}};
88

99
#[derive(Clone, Debug)]
1010
pub enum ParsingASTTypeMember {
11-
Generic(String, Vec<Box<ASTType>>, Vec<usize>),
11+
Generic(String, Vec<Box<ASTType>>, Vec<usize>, Option<String>),
1212
Pointer(bool),
1313
Reference,
1414
Array(usize)
@@ -47,7 +47,7 @@ pub fn parse_type_type_parameters(tokens: &Vec<LexerToken>, ind: &mut usize) ->
4747

4848
types.push(parsed_type);
4949

50-
if tokens[*ind].tok_type == LexerTokenType::AngelBracketClose {
50+
if tokens[*ind].is_angel_bracket_close() {
5151
break;
5252
}
5353

@@ -65,10 +65,26 @@ pub fn parse_type_generic(tokens: &Vec<LexerToken>, ind: &mut usize) -> Diagnost
6565

6666
*ind += 1;
6767

68+
let specifier;
69+
70+
if tokens[*ind].tok_type == LexerTokenType::Collon {
71+
*ind += 1;
72+
73+
tokens[*ind].expects(LexerTokenType::Collon)?;
74+
*ind += 1;
75+
76+
specifier = Some(tokens[*ind].expects_keyword()?.0);
77+
*ind += 1;
78+
} else {
79+
specifier = None;
80+
}
81+
82+
println!("{:#?}", specifier.clone());
83+
6884
let sizes = parse_type_size_specifiers(tokens, ind)?;
6985
let types = parse_type_type_parameters(tokens, ind)?;
7086

71-
return Ok(ParsingASTTypeMember::Generic(type_name.0, types, sizes))
87+
return Ok(ParsingASTTypeMember::Generic(type_name.0, types, sizes, specifier))
7288
}
7389

7490
pub fn parse_type_member(tokens: &Vec<LexerToken>, ind: &mut usize, took_generic: bool) -> DiagnosticResult<Option<ParsingASTTypeMember>> {
@@ -147,7 +163,7 @@ pub fn parse_type(tokens: &Vec<LexerToken>, ind: &mut usize) -> DiagnosticResult
147163
let parsed_member = parse_type_member(tokens, ind, took_generic)?;
148164

149165
if let Some(value) = parsed_member {
150-
if let ParsingASTTypeMember::Generic(_, _, _) = &value {
166+
if let ParsingASTTypeMember::Generic(_, _, _, _) = &value {
151167
took_generic = true;
152168
}
153169

@@ -161,7 +177,7 @@ pub fn parse_type(tokens: &Vec<LexerToken>, ind: &mut usize) -> DiagnosticResult
161177

162178
for i in 0..members.len() {
163179
let converted_member = match members[i].clone() {
164-
ParsingASTTypeMember::Generic(t, types, sizes) => ASTType::Generic(t, types, sizes),
180+
ParsingASTTypeMember::Generic(t, types, sizes, specifier) => ASTType::Generic(t, types, sizes, specifier),
165181
ParsingASTTypeMember::Pointer(array) => ASTType::Pointer(array, child.unwrap()),
166182
ParsingASTTypeMember::Reference => ASTType::Reference(child.unwrap()),
167183
ParsingASTTypeMember::Array(size) => ASTType::Array(size, child.unwrap())

compiler/ast_parser/src/unwraps.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use ast::tree::{ASTTreeNode, ASTTreeNodeKind};
2+
use compiler_utils::hash::HashedString;
3+
use diagnostics::{DiagnosticResult};
4+
use lexer::token::{LexerToken, LexerTokenType};
5+
6+
use crate::{types::parse_type, value::parse_ast_value};
7+
8+
pub fn parse_unwrap_condition(tokens: &Vec<LexerToken>, ind: &mut usize) -> DiagnosticResult<Box<ASTTreeNode>> {
9+
let start = tokens[*ind].pos.clone();
10+
11+
let unsafe_unwrap = tokens[*ind].tok_type == LexerTokenType::UnwrapUnsafe;
12+
*ind += 1;
13+
14+
tokens[*ind].expects(LexerTokenType::AngelBracketOpen)?;
15+
*ind += 1;
16+
17+
let original = parse_ast_value(tokens, ind)?;
18+
19+
tokens[*ind].expects(LexerTokenType::Comma)?;
20+
*ind += 1;
21+
22+
let new_type = parse_type(tokens, ind)?;
23+
24+
let new_var: Option<HashedString>;
25+
if tokens[*ind].tok_type == LexerTokenType::AngelBracketClose {
26+
new_var = None;
27+
} else {
28+
tokens[*ind].expects(LexerTokenType::Comma)?;
29+
*ind += 1;
30+
31+
let kwd = tokens[*ind].expects_keyword()?;
32+
33+
new_var = Some(HashedString::new(kwd.0));
34+
35+
*ind += 1;
36+
tokens[*ind].expects(LexerTokenType::AngelBracketClose)?;
37+
}
38+
39+
*ind += 1;
40+
return Ok(Box::new(ASTTreeNode::new(ASTTreeNodeKind::UnwrapCondition { original, target_type: new_type, unsafe_unwrap, target_var: new_var }, start, tokens[*ind].get_end_pos())))
41+
}
42+
43+
pub fn parse_unwrap_value(tokens: &Vec<LexerToken>, ind: &mut usize) -> DiagnosticResult<Box<ASTTreeNode>> {
44+
let start = tokens[*ind].pos.clone();
45+
46+
let unsafe_unwrap = tokens[*ind].tok_type == LexerTokenType::UnwrapUnsafe;
47+
*ind += 1;
48+
49+
tokens[*ind].expects(LexerTokenType::AngelBracketOpen)?;
50+
*ind += 1;
51+
52+
let original = parse_ast_value(tokens, ind)?;
53+
54+
tokens[*ind].expects(LexerTokenType::Comma)?;
55+
*ind += 1;
56+
57+
let new_type = parse_type(tokens, ind)?;
58+
59+
tokens[*ind].expects(LexerTokenType::AngelBracketClose)?;
60+
61+
*ind += 1;
62+
return Ok(Box::new(ASTTreeNode::new(ASTTreeNodeKind::UnwrapValue { original, target_type: new_type, unsafe_unwrap }, start, tokens[*ind].get_end_pos())))
63+
}

compiler/ast_parser/src/value.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use ast::{make_node, tree::{ASTTreeNode, ASTTreeNodeKind}};
44
use diagnostics::{DiagnosticResult, builders::{make_expected_simple_error, make_unexpected_simple_error}};
55
use lexer::token::{LexerToken, LexerTokenType};
66

7-
use crate::{arrays::parse_array_access, functions::parse_function_call, structs::val::parse_struct_initialize};
7+
use crate::{arrays::parse_array_access, functions::parse_function_call, structs::val::parse_struct_initialize, unwraps::{parse_unwrap_condition, parse_unwrap_value}};
88
use crate::literals::{parse_integer_literal, parse_string_literal};
99
use crate::math::parse_math_operation;
1010

@@ -137,6 +137,13 @@ pub fn parse_ast_value_post_l(tokens: &Vec<LexerToken>, ind: &mut usize, origina
137137
}
138138
}
139139

140+
pub fn parse_ast_condition_if_statement_value(tokens: &Vec<LexerToken>, ind: &mut usize) -> DiagnosticResult<Box<ASTTreeNode>> {
141+
match &tokens[*ind].tok_type {
142+
LexerTokenType::Unwrap | LexerTokenType::UnwrapUnsafe => parse_unwrap_condition(tokens, ind),
143+
_ => parse_ast_value(tokens, ind)
144+
}
145+
}
146+
140147
/// Parses an AST node that can and WILL be intrepreted as a value
141148
///
142149
/// # Parsing Layout
@@ -204,7 +211,9 @@ pub fn parse_ast_value(tokens: &Vec<LexerToken>, ind: &mut usize) -> DiagnosticR
204211
let chain = parse_ast_value_dotacess(tokens, ind, n);
205212

206213
return parse_ast_value_post_l(tokens, ind, chain, false);
207-
}
214+
},
215+
216+
LexerTokenType::Unwrap | LexerTokenType::UnwrapUnsafe => parse_unwrap_value(tokens, ind),
208217

209218
_=> return Err(make_unexpected_simple_error(&tokens[*ind], &tokens[*ind].tok_type).into())
210219
}

compiler/astoir_hir/src/ctx.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,30 @@ impl HIRBranchedContext {
6161
return self.current_branch;
6262
}
6363

64+
/// Introduces a new variable in the next branch era
65+
pub fn introduce_variable_next_era(&mut self, hash: u64, t: Type, has_default: bool) -> Result<usize, ()> {
66+
let identity = SelfHash { hash };
67+
68+
if self.hash_to_ind.contains_key(&identity) {
69+
return Err(());
70+
}
71+
72+
let mut var: HIRBranchedVariable = HIRBranchedVariable { introduced_in_era: self.current_branch + 1, variable_type: t, has_default, introduced_values: HashSet::new(), requires_address: false, mutation_count: 0 };
73+
74+
if has_default {
75+
var.mutation_count += 1;
76+
}
77+
78+
self.variables.push(var);
79+
80+
let ind: usize = self.current_element_index;
81+
self.current_element_index += 1;
82+
83+
self.hash_to_ind.insert(identity, ind);
84+
85+
return Ok(ind);
86+
}
87+
6488
/// Introduces a new variable in the current branch era.
6589
pub fn introduce_variable(&mut self, hash: u64, t: Type, has_default: bool) -> Result<usize, ()> {
6690
let identity = SelfHash { hash };

compiler/astoir_hir/src/nodes.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! The nodes inside of the AstoIR HIR.
22
3-
use compiler_typing::{references::TypeReference, storage::{BOOLEAN_TYPE, STATIC_STR}, structs::RawStructTypeContainer, transmutation::array::can_transmute_inner, tree::Type};
3+
use compiler_typing::{raw::RawType, references::TypeReference, storage::{BOOLEAN_TYPE, STATIC_STR}, structs::RawStructTypeContainer, transmutation::array::can_transmute_inner, tree::Type};
44
use compiler_utils::Position;
55
use diagnostics::{DiagnosticSpanOrigin, builders::{make_diff_type, make_diff_type_val}, diagnostic::{Diagnostic, Span, SpanKind, SpanPosition}, unsure_panic};
66
use lexer::toks::{comp::ComparingOperator, math::MathOperator};
@@ -51,6 +51,9 @@ pub enum HIRNodeKind {
5151

5252
MathOperation { left: Box<HIRNode>, right: Box<HIRNode>, operation: MathOperator, assignment: bool },
5353

54+
UnwrapCondition { original: Box<HIRNode>, new_type: Type, new_var: Option<usize>, unsafe_unwrap: bool },
55+
UnwrapValue { original: Box<HIRNode>, new_type: Type, unsafe_unwrap: bool },
56+
5457
VariableReference { index: usize, is_static: bool },
5558
FunctionReference { index: usize },
5659

@@ -172,10 +175,10 @@ impl HIRNode {
172175
}
173176

174177
if let Some(v) = var_origin {
175-
return Err(make_diff_type(origin, &"unnamed".to_string(), &t, &self.get_node_type(context, curr_ctx).unwrap(), v).into())
178+
return Err(make_diff_type(origin, &"unnamed".to_string(), &t.faulty_lowering_generic(&context.type_storage), &self.get_node_type(context, curr_ctx).unwrap().faulty_lowering_generic(&context.type_storage), v).into())
176179
}
177180

178-
return Err(make_diff_type_val(origin, &t, &self.get_node_type(context, curr_ctx).unwrap()).into())
181+
return Err(make_diff_type_val(origin, &t.faulty_lowering_generic(&context.type_storage), &self.get_node_type(context, curr_ctx).unwrap().faulty_lowering_generic(&context.type_storage)).into())
179182
}
180183

181184
pub fn get_node_type(&self, context: &HIRContext, curr_ctx: &HIRBranchedContext) -> Option<Type> {
@@ -196,6 +199,14 @@ impl HIRNode {
196199
return Some(Type::Reference(Box::new(val.get_node_type(context, curr_ctx).unwrap())))
197200
}
198201

202+
HIRNodeKind::UnwrapCondition { .. } => {
203+
return Some(Type::Generic(RawType::Boolean, vec![], vec![]))
204+
},
205+
206+
HIRNodeKind::UnwrapValue { original: _, new_type, unsafe_unwrap: _ } => {
207+
return Some(new_type.clone())
208+
},
209+
199210
HIRNodeKind::ArrayIndexAccess { val, index: _ } => {
200211
let t = val.get_node_type(context, curr_ctx).unwrap();
201212

@@ -212,7 +223,7 @@ impl HIRNode {
212223
None => return None
213224
};
214225

215-
return Some(Type::Generic(ind, vec![], vec![]))
226+
return Some(Type::Generic(RawType::Boolean, vec![], vec![]))
216227
},
217228

218229
HIRNodeKind::ArrayVariableInitializerValue { vals } => return Some(Type::Array(vals.len(), Box::new(vals[0].get_node_type(context, curr_ctx).unwrap()))),
@@ -227,12 +238,7 @@ impl HIRNode {
227238
},
228239

229240
HIRNodeKind::BooleanOperator { .. } | HIRNodeKind::BooleanCondition { .. } => {
230-
let t = match context.type_storage.types.get_index(BOOLEAN_TYPE) {
231-
Some(v) => v,
232-
None => return None
233-
};
234-
235-
return Some(Type::Generic(t, vec![], vec![]))
241+
return Some(Type::Generic(RawType::Boolean, vec![], vec![]))
236242
},
237243

238244
HIRNodeKind::StructVariableInitializerValue { t, fields: _ } => {

0 commit comments

Comments
 (0)