Skip to content

Commit e557599

Browse files
committed
Refactor AST and Builder to integrate SymbolType and TypedAst; update dependencies and add tests for UzumakiExpression
1 parent 1d35e54 commit e557599

File tree

16 files changed

+265
-85
lines changed

16 files changed

+265
-85
lines changed

ast/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ homepage = { workspace = true }
77
repository = { workspace = true }
88

99
[dependencies]
10-
serde = { version = "1.0.217", features = ["derive", "rc"] }
1110
uuid = { version = "1.1", features = ["v4"] }
1211
tree-sitter.workspace = true
1312
anyhow.workspace = true

ast/src/arena.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@ use crate::types::AstNode;
44

55
#[derive(Default, Clone)]
66
pub(crate) struct Arena {
7-
nodes: HashMap<u32, AstNode>,
8-
node_routes: Vec<NodeRoute>,
7+
pub(crate) nodes: HashMap<u32, AstNode>,
8+
pub(crate) node_routes: Vec<NodeRoute>,
99
}
1010

1111
impl Arena {
1212
pub fn add_node(&mut self, node: AstNode, parent_id: u32) {
13+
// println!("Adding node with ID: {node:?}");
1314
assert!(node.id() != 0, "Node ID must be non-zero");
1415
assert!(
1516
!self.nodes.contains_key(&node.id()),
16-
"Node already exists in the arena"
17+
"Node with ID {} already exists in the arena",
18+
node.id()
1719
);
1820
let id = node.id();
1921
self.nodes.insert(node.id(), node);
@@ -43,7 +45,17 @@ impl Arena {
4345
.and_then(|node| node.parent)
4446
}
4547

46-
// pub fn check_expressions_typed(&self) {}
48+
// pub fn check_expressions_typed(&self) {
49+
// for node in self.nodes.values() {
50+
// match &node {
51+
// AstNode::UzumakiExpression(expr) => {
52+
// assert!(
53+
// expr.ty
54+
// )
55+
// }
56+
// }
57+
// }
58+
// }
4759
}
4860

4961
#[derive(Clone, Default)]

ast/src/builder.rs

Lines changed: 85 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
use std::{collections::HashMap, marker::PhantomData, rc::Rc};
1+
use std::{marker::PhantomData, rc::Rc};
22

33
use crate::{
44
arena::Arena,
5+
symbols::{SymbolTable, SymbolType},
6+
t_ast::TypedAst,
57
types::{
68
ArrayIndexAccessExpression, ArrayLiteral, AssertStatement, AssignExpression, AstNode,
7-
BinaryExpression, Block, BoolLiteral, BreakStatement, ConstantDefinition, Definition,
8-
EnumDefinition, Expression, ExternalFunctionDefinition, FunctionCallExpression,
9+
BinaryExpression, Block, BlockType, BoolLiteral, BreakStatement, ConstantDefinition,
10+
Definition, EnumDefinition, Expression, ExternalFunctionDefinition, FunctionCallExpression,
911
FunctionDefinition, FunctionType, GenericType, Identifier, IfStatement, Literal, Location,
1012
LoopStatement, MemberAccessExpression, NumberLiteral, OperatorKind, Parameter,
1113
ParenthesizedExpression, PrefixUnaryExpression, QualifiedName, ReturnStatement, SimpleType,
@@ -16,8 +18,6 @@ use crate::{
1618
};
1719
use tree_sitter::Node;
1820

19-
use super::types::BlockType;
20-
2121
#[allow(dead_code)]
2222
trait BuilderInit {}
2323
#[allow(dead_code)]
@@ -28,17 +28,12 @@ impl BuilderInit for InitState {}
2828
pub struct CompleteState;
2929
impl BuilderComplete for CompleteState {}
3030

31-
pub enum Scope {
32-
Global,
33-
Inner(String),
34-
}
35-
3631
#[allow(dead_code)]
3732
pub struct Builder<'a, S> {
3833
arena: Arena,
3934
source_code: Vec<(Node<'a>, &'a [u8])>,
40-
types_table: HashMap<String, Scope>,
41-
t_ast: Vec<SourceFile>,
35+
types: Vec<SymbolType>,
36+
t_ast: Option<TypedAst>,
4237
_state: PhantomData<S>,
4338
}
4439

@@ -54,8 +49,8 @@ impl<'a> Builder<'a, InitState> {
5449
Self {
5550
arena: Arena::default(),
5651
source_code: Vec::new(),
57-
types_table: HashMap::new(),
58-
t_ast: Vec::new(),
52+
types: Vec::new(),
53+
t_ast: None,
5954
_state: PhantomData,
6055
}
6156
}
@@ -107,11 +102,13 @@ impl<'a> Builder<'a, InitState> {
107102
}
108103
res.push(ast);
109104
}
105+
let symbol_table = SymbolTable::build(self.types.clone(), &res);
106+
let t_ast = TypedAst::new(res, symbol_table, self.arena.clone());
110107
Ok(Builder {
111-
arena: self.arena.clone(),
108+
arena: Arena::default(),
112109
source_code: Vec::new(),
113-
types_table: HashMap::new(),
114-
t_ast: res,
110+
types: Vec::new(),
111+
t_ast: Some(t_ast),
115112
_state: PhantomData,
116113
})
117114
}
@@ -209,6 +206,7 @@ impl<'a> Builder<'a, InitState> {
209206
variants = founded_variants;
210207
}
211208

209+
self.types.push(SymbolType::Inner(name.name.clone()));
212210
let node = Rc::new(EnumDefinition::new(id, name, variants, location));
213211
self.arena
214212
.add_node(AstNode::EnumDefinition(node.clone()), parent_id);
@@ -259,7 +257,6 @@ impl<'a> Builder<'a, InitState> {
259257
let name =
260258
self.build_identifier(id, &node.child_by_field_name("struct_name").unwrap(), code);
261259
let mut fields = Vec::new();
262-
263260
let mut cursor = node.walk();
264261
let founded_fields = node
265262
.children_by_field_name("field", &mut cursor)
@@ -268,7 +265,6 @@ impl<'a> Builder<'a, InitState> {
268265
if !founded_fields.is_empty() {
269266
fields = founded_fields;
270267
}
271-
272268
cursor = node.walk();
273269
let founded_methods = node
274270
.children_by_field_name("method", &mut cursor)
@@ -302,10 +298,15 @@ impl<'a> Builder<'a, InitState> {
302298
let id = Self::get_node_id();
303299
let location = Self::get_location(node, code);
304300
let name = self.build_identifier(id, &node.child_by_field_name("name").unwrap(), code);
305-
let type_ = self.build_type(id, &node.child_by_field_name("type").unwrap(), code);
306-
let value = self.build_literal(id, &node.child_by_field_name("value").unwrap(), code);
301+
let ty = self.build_type(id, &node.child_by_field_name("type").unwrap(), code);
302+
let value = self.build_literal(
303+
id,
304+
&node.child_by_field_name("value").unwrap(),
305+
code,
306+
Some(Self::symbol_type_from_ast_type(ty.clone())),
307+
);
307308

308-
let node = Rc::new(ConstantDefinition::new(id, name, type_, value, location));
309+
let node = Rc::new(ConstantDefinition::new(id, name, ty, value, location));
309310
self.arena
310311
.add_node(AstNode::ConstantDefinition(node.clone()), parent_id);
311312
node
@@ -421,7 +422,7 @@ impl<'a> Builder<'a, InitState> {
421422
&node.child_by_field_name("body").unwrap(),
422423
code,
423424
);
424-
let node = Rc::new(Block::new(parent_id, location, statements));
425+
let node = Rc::new(Block::new(id, location, statements));
425426
self.arena.add_node(AstNode::Block(node.clone()), parent_id);
426427
BlockType::Assume(node)
427428
}
@@ -431,7 +432,7 @@ impl<'a> Builder<'a, InitState> {
431432
&node.child_by_field_name("body").unwrap(),
432433
code,
433434
);
434-
let node = Rc::new(Block::new(parent_id, location, statements));
435+
let node = Rc::new(Block::new(id, location, statements));
435436
self.arena.add_node(AstNode::Block(node.clone()), parent_id);
436437
BlockType::Forall(node)
437438
}
@@ -441,7 +442,7 @@ impl<'a> Builder<'a, InitState> {
441442
&node.child_by_field_name("body").unwrap(),
442443
code,
443444
);
444-
let node = Rc::new(Block::new(parent_id, location, statements));
445+
let node = Rc::new(Block::new(id, location, statements));
445446
self.arena.add_node(AstNode::Block(node.clone()), parent_id);
446447
BlockType::Exists(node)
447448
}
@@ -451,13 +452,13 @@ impl<'a> Builder<'a, InitState> {
451452
&node.child_by_field_name("body").unwrap(),
452453
code,
453454
);
454-
let node = Rc::new(Block::new(parent_id, location, statements));
455+
let node = Rc::new(Block::new(id, location, statements));
455456
self.arena.add_node(AstNode::Block(node.clone()), parent_id);
456457
BlockType::Unique(node)
457458
}
458459
"block" => {
459460
let statemetns = self.build_block_statements(id, node, code);
460-
let node = Rc::new(Block::new(parent_id, location, statemetns));
461+
let node = Rc::new(Block::new(id, location, statemetns));
461462
self.arena.add_node(AstNode::Block(node.clone()), parent_id);
462463
BlockType::Block(node)
463464
}
@@ -585,9 +586,14 @@ impl<'a> Builder<'a, InitState> {
585586
let location = Self::get_location(node, code);
586587
let ty = self.build_type(id, &node.child_by_field_name("type").unwrap(), code);
587588
let name = self.build_identifier(id, &node.child_by_field_name("name").unwrap(), code);
588-
let value = node
589-
.child_by_field_name("value")
590-
.map(|n| self.build_expression(id, &n, code, Some(ty.clone())));
589+
let value = node.child_by_field_name("value").map(|n| {
590+
self.build_expression(
591+
id,
592+
&n,
593+
code,
594+
Some(Self::symbol_type_from_ast_type(ty.clone())),
595+
)
596+
});
591597
let is_undef = node.child_by_field_name("undef").is_some();
592598

593599
let node = Rc::new(VariableDefinitionStatement::new(
@@ -622,7 +628,7 @@ impl<'a> Builder<'a, InitState> {
622628
parent_id: u32,
623629
node: &Node,
624630
code: &[u8],
625-
ty: Option<Type>,
631+
ty: Option<SymbolType>,
626632
) -> Expression {
627633
let node_kind = node.kind();
628634
match node_kind {
@@ -649,10 +655,13 @@ impl<'a> Builder<'a, InitState> {
649655
Expression::Binary(self.build_binary_expression(parent_id, node, code))
650656
}
651657
"bool_literal" | "string_literal" | "number_literal" | "array_literal"
652-
| "unit_literal" => Expression::Literal(self.build_literal(parent_id, node, code)),
653-
"uzumaki_keyword" => {
654-
Expression::Uzumaki(self.build_uzumaki_expression(parent_id, node, code, ty))
655-
}
658+
| "unit_literal" => Expression::Literal(self.build_literal(parent_id, node, code, ty)),
659+
"uzumaki_keyword" => Expression::Uzumaki(self.build_uzumaki_expression(
660+
parent_id,
661+
node,
662+
code,
663+
ty.unwrap(),
664+
)),
656665
"identifier" => Expression::Identifier(self.build_identifier(parent_id, node, code)),
657666
_ => panic!("Unexpected expression node kind: {node_kind}"),
658667
}
@@ -886,12 +895,20 @@ impl<'a> Builder<'a, InitState> {
886895
node
887896
}
888897

889-
fn build_literal(&mut self, parent_id: u32, node: &Node, code: &[u8]) -> Literal {
898+
fn build_literal(
899+
&mut self,
900+
parent_id: u32,
901+
node: &Node,
902+
code: &[u8],
903+
ty: Option<SymbolType>,
904+
) -> Literal {
890905
match node.kind() {
891906
"array_literal" => Literal::Array(self.build_array_literal(parent_id, node, code)),
892907
"bool_literal" => Literal::Bool(self.build_bool_literal(parent_id, node, code)),
893908
"string_literal" => Literal::String(self.build_string_literal(parent_id, node, code)),
894-
"number_literal" => Literal::Number(self.build_number_literal(parent_id, node, code)),
909+
"number_literal" => {
910+
Literal::Number(self.build_number_literal(parent_id, node, code, ty))
911+
}
895912
"unit_literal" => Literal::Unit(self.build_unit_literal(parent_id, node, code)),
896913
_ => panic!("Unexpected literal type: {}", node.kind()),
897914
}
@@ -941,7 +958,6 @@ impl<'a> Builder<'a, InitState> {
941958
let id = Self::get_node_id();
942959
let location = Self::get_location(node, code);
943960
let value = node.utf8_text(code).unwrap().to_string();
944-
945961
let node = Rc::new(StringLiteral::new(id, location, value));
946962
self.arena
947963
.add_node(AstNode::StringLiteral(node.clone()), parent_id);
@@ -953,22 +969,12 @@ impl<'a> Builder<'a, InitState> {
953969
parent_id: u32,
954970
node: &Node,
955971
code: &[u8],
972+
ty: Option<SymbolType>,
956973
) -> Rc<NumberLiteral> {
957974
let id = Self::get_node_id();
958975
let location = Self::get_location(node, code);
959976
let value = node.utf8_text(code).unwrap().to_string();
960-
961-
//FIXME hack
962-
let node = Rc::new(NumberLiteral::new(
963-
id,
964-
location,
965-
value,
966-
Type::Simple(Rc::new(SimpleType::new(
967-
id,
968-
Location::default(),
969-
"i32".to_string(),
970-
))),
971-
));
977+
let node = Rc::new(NumberLiteral::new(id, location, value, ty.unwrap()));
972978
self.arena
973979
.add_node(AstNode::NumberLiteral(node.clone()), parent_id);
974980
node
@@ -1013,9 +1019,14 @@ impl<'a> Builder<'a, InitState> {
10131019
let id = Self::get_node_id();
10141020
let location = Self::get_location(node, code);
10151021
let element_type = self.build_type(id, &node.child_by_field_name("type").unwrap(), code);
1016-
let size = node
1017-
.child_by_field_name("length")
1018-
.map(|n| Box::new(self.build_expression(id, &n, code, Some(element_type.clone()))));
1022+
let size = node.child_by_field_name("length").map(|n| {
1023+
Box::new(self.build_expression(
1024+
id,
1025+
&n,
1026+
code,
1027+
Some(Self::symbol_type_from_ast_type(element_type.clone())),
1028+
))
1029+
});
10191030

10201031
let node = Rc::new(TypeArray::new(id, location, Box::new(element_type), size));
10211032
self.arena
@@ -1027,7 +1038,7 @@ impl<'a> Builder<'a, InitState> {
10271038
let id = Self::get_node_id();
10281039
let location = Self::get_location(node, code);
10291040
let name = node.utf8_text(code).unwrap().to_string();
1030-
self.types_table.insert(name.clone(), Scope::Global);
1041+
self.types.push(SymbolType::Global(name.clone()));
10311042
let node = Rc::new(SimpleType::new(id, location, name));
10321043
self.arena
10331044
.add_node(AstNode::SimpleType(node.clone()), parent_id);
@@ -1122,11 +1133,11 @@ impl<'a> Builder<'a, InitState> {
11221133
parent_id: u32,
11231134
node: &Node,
11241135
code: &[u8],
1125-
ty: Option<Type>,
1136+
ty: SymbolType,
11261137
) -> Rc<UzumakiExpression> {
11271138
let id = Self::get_node_id();
11281139
let location = Self::get_location(node, code);
1129-
let node = Rc::new(UzumakiExpression::new(id, location, ty.unwrap()));
1140+
let node = Rc::new(UzumakiExpression::new(id, location, ty));
11301141
self.arena
11311142
.add_node(AstNode::UzumakiExpression(node.clone()), parent_id);
11321143
node
@@ -1142,6 +1153,18 @@ impl<'a> Builder<'a, InitState> {
11421153
node
11431154
}
11441155

1156+
fn symbol_type_from_ast_type(ty: Type) -> SymbolType {
1157+
match ty {
1158+
Type::Array(_) => SymbolType::Inner("array".to_string()), //TODO implement
1159+
Type::Simple(t) => SymbolType::Global(t.name.clone()),
1160+
Type::Generic(_) => SymbolType::Inner("generic".to_string()), //TODO implement
1161+
Type::Qualified(_) => SymbolType::Inner("qualified".to_string()), //TODO implement
1162+
Type::QualifiedName(_) => SymbolType::Inner("qualified_name".to_string()), //TODO implement
1163+
Type::Function(_) => SymbolType::Inner("function".to_string()), //TODO implement
1164+
Type::Custom(_) => SymbolType::Inner("custom".to_string()), //TODO implement
1165+
}
1166+
}
1167+
11451168
#[allow(clippy::cast_possible_truncation)]
11461169
fn get_node_id() -> u32 {
11471170
uuid::Uuid::new_v4().as_u128() as u32
@@ -1173,8 +1196,12 @@ impl<'a> Builder<'a, InitState> {
11731196

11741197
impl Builder<'_, CompleteState> {
11751198
/// Returns typed AST
1199+
///
1200+
/// # Panics
1201+
///
1202+
/// This function will panic if resulted `TypedAst` is `None` which means an error occured during the parsing process.
11761203
#[must_use]
1177-
pub fn t_ast(self) -> Vec<SourceFile> {
1178-
self.t_ast
1204+
pub fn t_ast(self) -> TypedAst {
1205+
self.t_ast.unwrap()
11791206
}
11801207
}

ast/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![warn(clippy::pedantic)]
22
pub(crate) mod arena;
33
pub mod builder;
4+
pub mod symbols;
5+
pub mod t_ast;
46
pub mod types;
57
pub(crate) mod types_impl;

0 commit comments

Comments
 (0)