Compare commits
No commits in common. "43c828d96fd0890d8d1875768651955330a98981" and "1bd6c43341215ac01c20ae3e7498140b9e70f4db" have entirely different histories.
43c828d96f
...
1bd6c43341
4
Makefile
4
Makefile
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
test:
|
|
||||||
cargo run --bin main -- -i tests/legal/call.sea asm > asm.S
|
|
||||||
clang asm.S -c && clang asm.o -o asm && ./asm; echo $$?
|
|
|
@ -2,6 +2,7 @@ use std::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
|
marker::PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
use num_bigint::{BigInt, BigUint, Sign};
|
use num_bigint::{BigInt, BigUint, Sign};
|
||||||
|
@ -378,7 +379,7 @@ pub struct Index(u32);
|
||||||
|
|
||||||
impl Display for Index {
|
impl Display for Index {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "${}", self.index())
|
write!(f, "#{}", self.index())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,7 +490,7 @@ static_keys!(
|
||||||
U128 => Key::UIntType { bit_width: 128 },
|
U128 => Key::UIntType { bit_width: 128 },
|
||||||
TRUE => Key::TrueValue,
|
TRUE => Key::TrueValue,
|
||||||
FALSE => Key::FalseValue,
|
FALSE => Key::FalseValue,
|
||||||
EMPTY_STRING => Key::String { str: "" },
|
EMPTY_STRING => Key::String { str: "<this string is empty>" },
|
||||||
EMPTY_BYTES => Key::Bytes { bytes: &[] },
|
EMPTY_BYTES => Key::Bytes { bytes: &[] },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
606
src/ast2/mod.rs
606
src/ast2/mod.rs
|
@ -977,17 +977,6 @@ impl Ast {
|
||||||
loc: SourceLocation,
|
loc: SourceLocation,
|
||||||
) -> Index {
|
) -> Index {
|
||||||
let i = self.reserve_node();
|
let i = self.reserve_node();
|
||||||
self.set_struct_decl(i, name, flags, fields, loc)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_struct_decl<I: IntoIterator<Item = (intern::Index, Index)>>(
|
|
||||||
&mut self,
|
|
||||||
i: Index,
|
|
||||||
name: intern::Index,
|
|
||||||
flags: StructFlags,
|
|
||||||
fields: I,
|
|
||||||
loc: SourceLocation,
|
|
||||||
) -> Index {
|
|
||||||
let (offset, _) = self.extend_extra([flags.pack()]);
|
let (offset, _) = self.extend_extra([flags.pack()]);
|
||||||
let (names, types) = fields
|
let (names, types) = fields
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -1276,10 +1265,7 @@ impl Ast {
|
||||||
{
|
{
|
||||||
return_type
|
return_type
|
||||||
} else {
|
} else {
|
||||||
eprintln!(
|
eprintln!("lhs of call expr is not a function!");
|
||||||
"lhs of call expr is not a function: {fn_ty}: {:?}",
|
|
||||||
ip.get_key(fn_ty)
|
|
||||||
);
|
|
||||||
void
|
void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2089,254 +2075,6 @@ pub fn interned_type_and_value_to_comptime_number(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use visitor::AstVisitor;
|
|
||||||
|
|
||||||
impl Ast {
|
|
||||||
pub fn visitor_mut(&mut self) -> AstVisitor<&mut Self> {
|
|
||||||
AstVisitor {
|
|
||||||
scopes: vec![],
|
|
||||||
nodes: self
|
|
||||||
.get_root_file_indices()
|
|
||||||
.map(|i| visitor::A::PushChildren(i))
|
|
||||||
.collect(),
|
|
||||||
ast: self,
|
|
||||||
rev: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn visitor_rev_mut(&mut self) -> AstVisitor<&mut Self> {
|
|
||||||
AstVisitor {
|
|
||||||
scopes: vec![],
|
|
||||||
nodes: self
|
|
||||||
.get_root_file_indices()
|
|
||||||
.map(|i| visitor::A::PushChildren(i))
|
|
||||||
.collect(),
|
|
||||||
ast: self,
|
|
||||||
rev: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn visitor(&self) -> AstVisitor<&Self> {
|
|
||||||
AstVisitor {
|
|
||||||
scopes: vec![],
|
|
||||||
nodes: self
|
|
||||||
.get_root_file_indices()
|
|
||||||
.map(|i| visitor::A::PushChildren(i))
|
|
||||||
.collect(),
|
|
||||||
ast: self,
|
|
||||||
rev: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod visitor {
|
|
||||||
use super::*;
|
|
||||||
pub trait AstExt {
|
|
||||||
fn get_node_children(&self, node: Index) -> Vec<Index>;
|
|
||||||
fn get_node_tag_and_data(&self, node: Index) -> (Tag, Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AstExt for &Ast {
|
|
||||||
fn get_node_children(&self, node: Index) -> Vec<Index> {
|
|
||||||
Ast::get_node_children(self, node)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_node_tag_and_data(&self, node: Index) -> (Tag, Data) {
|
|
||||||
(self.tags[node.index()], self.datas[node.index()])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl AstExt for &mut Ast {
|
|
||||||
fn get_node_children(&self, node: Index) -> Vec<Index> {
|
|
||||||
Ast::get_node_children(self, node)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_node_tag_and_data(&self, node: Index) -> (Tag, Data) {
|
|
||||||
(self.tags[node.index()], self.datas[node.index()])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AstVisitor<AstT> {
|
|
||||||
pub(super) ast: AstT,
|
|
||||||
pub(super) scopes: Vec<Index>,
|
|
||||||
pub(super) nodes: Vec<A>,
|
|
||||||
pub(super) rev: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<AstT> AstVisitor<AstT>
|
|
||||||
where
|
|
||||||
AstT: AstExt,
|
|
||||||
{
|
|
||||||
pub fn visit<
|
|
||||||
F: FnMut(&mut AstT, &[Index], Index, Tag, Data),
|
|
||||||
G: FnMut(&mut AstT, &[Index], Index, Tag, Data),
|
|
||||||
>(
|
|
||||||
&mut self,
|
|
||||||
mut pre: F,
|
|
||||||
mut post: G,
|
|
||||||
) {
|
|
||||||
while let Some(node) = self.nodes.pop() {
|
|
||||||
match node {
|
|
||||||
A::PushChildren(i) => {
|
|
||||||
self.nodes.push(A::PopSelf(i));
|
|
||||||
let children_iter = self
|
|
||||||
.ast
|
|
||||||
.get_node_children(i)
|
|
||||||
.into_iter()
|
|
||||||
.map(|i| A::PushChildren(i));
|
|
||||||
// inverse because we are popping from the end
|
|
||||||
if !self.rev {
|
|
||||||
self.nodes.extend(children_iter.rev())
|
|
||||||
} else {
|
|
||||||
self.nodes.extend(children_iter)
|
|
||||||
};
|
|
||||||
|
|
||||||
let (tag, data) = self.ast.get_node_tag_and_data(i);
|
|
||||||
|
|
||||||
let _ = pre(&mut self.ast, &self.scopes, i, tag, data);
|
|
||||||
|
|
||||||
match tag {
|
|
||||||
Tag::File
|
|
||||||
| Tag::FunctionDecl
|
|
||||||
| Tag::GlobalDecl
|
|
||||||
| Tag::Block
|
|
||||||
| Tag::BlockTrailingExpr => {
|
|
||||||
self.scopes.push(i);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
A::PopSelf(i) => {
|
|
||||||
// already popped.
|
|
||||||
let (tag, data) = self.ast.get_node_tag_and_data(i);
|
|
||||||
|
|
||||||
let _ = post(&mut self.ast, &self.scopes, i, tag, data);
|
|
||||||
|
|
||||||
match tag {
|
|
||||||
Tag::File
|
|
||||||
| Tag::FunctionDecl
|
|
||||||
| Tag::GlobalDecl
|
|
||||||
| Tag::Block
|
|
||||||
| Tag::BlockTrailingExpr => {
|
|
||||||
self.scopes.pop();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn visit_pre<F: FnMut(&mut AstT, &[Index], Index, Tag, Data)>(
|
|
||||||
&mut self,
|
|
||||||
mut cb: F,
|
|
||||||
) {
|
|
||||||
while let Some(node) = self.nodes.pop() {
|
|
||||||
match node {
|
|
||||||
A::PushChildren(i) => {
|
|
||||||
self.nodes.push(A::PopSelf(i));
|
|
||||||
let children_iter = self
|
|
||||||
.ast
|
|
||||||
.get_node_children(i)
|
|
||||||
.into_iter()
|
|
||||||
.map(|i| A::PushChildren(i));
|
|
||||||
// inverse because we are popping from the end
|
|
||||||
if !self.rev {
|
|
||||||
self.nodes.extend(children_iter.rev())
|
|
||||||
} else {
|
|
||||||
self.nodes.extend(children_iter)
|
|
||||||
};
|
|
||||||
|
|
||||||
let (tag, data) = self.ast.get_node_tag_and_data(i);
|
|
||||||
|
|
||||||
let _ = cb(&mut self.ast, &self.scopes, i, tag, data);
|
|
||||||
|
|
||||||
match tag {
|
|
||||||
Tag::File
|
|
||||||
| Tag::FunctionDecl
|
|
||||||
| Tag::GlobalDecl
|
|
||||||
| Tag::Block
|
|
||||||
| Tag::BlockTrailingExpr => {
|
|
||||||
self.scopes.push(i);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
A::PopSelf(i) => {
|
|
||||||
// already popped.
|
|
||||||
let (tag, _data) = self.ast.get_node_tag_and_data(i);
|
|
||||||
|
|
||||||
match tag {
|
|
||||||
Tag::File
|
|
||||||
| Tag::FunctionDecl
|
|
||||||
| Tag::GlobalDecl
|
|
||||||
| Tag::Block
|
|
||||||
| Tag::BlockTrailingExpr => {
|
|
||||||
self.scopes.pop();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn visit_post<F: FnMut(&mut AstT, &[Index], Index, Tag, Data)>(
|
|
||||||
&mut self,
|
|
||||||
mut cb: F,
|
|
||||||
) {
|
|
||||||
while let Some(node) = self.nodes.pop() {
|
|
||||||
match node {
|
|
||||||
A::PushChildren(i) => {
|
|
||||||
self.nodes.push(A::PopSelf(i));
|
|
||||||
let children_iter = self
|
|
||||||
.ast
|
|
||||||
.get_node_children(i)
|
|
||||||
.into_iter()
|
|
||||||
.map(|i| A::PushChildren(i));
|
|
||||||
if self.rev {
|
|
||||||
self.nodes.extend(children_iter.rev())
|
|
||||||
} else {
|
|
||||||
self.nodes.extend(children_iter)
|
|
||||||
};
|
|
||||||
|
|
||||||
let (tag, _data) = self.ast.get_node_tag_and_data(i);
|
|
||||||
|
|
||||||
match tag {
|
|
||||||
Tag::File
|
|
||||||
| Tag::FunctionDecl
|
|
||||||
| Tag::GlobalDecl
|
|
||||||
| Tag::Block
|
|
||||||
| Tag::BlockTrailingExpr => {
|
|
||||||
self.scopes.push(i);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
A::PopSelf(i) => {
|
|
||||||
// already popped.
|
|
||||||
let (tag, data) = self.ast.get_node_tag_and_data(i);
|
|
||||||
|
|
||||||
let _ = cb(&mut self.ast, &self.scopes, i, tag, data);
|
|
||||||
|
|
||||||
match tag {
|
|
||||||
Tag::File
|
|
||||||
| Tag::FunctionDecl
|
|
||||||
| Tag::GlobalDecl
|
|
||||||
| Tag::Block
|
|
||||||
| Tag::BlockTrailingExpr => {
|
|
||||||
self.scopes.pop();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum A {
|
|
||||||
PushChildren(Index),
|
|
||||||
PopSelf(Index),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AstRenderer<'a> {
|
pub struct AstRenderer<'a> {
|
||||||
ast: &'a Ast,
|
ast: &'a Ast,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -2390,21 +2128,37 @@ impl<'a> AstRenderer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render<W: core::fmt::Write>(&mut self, w: &mut W) -> core::fmt::Result {
|
fn render_node<W: core::fmt::Write>(
|
||||||
self.ast.visitor().visit_pre(|ast, scopes, node, tag, _| {
|
&mut self,
|
||||||
let loc = ast.source_locs[node.index()];
|
w: &mut W,
|
||||||
|
indent: u32,
|
||||||
|
node: Index,
|
||||||
|
) -> core::fmt::Result {
|
||||||
|
let tag = self.ast.tags[node.index()];
|
||||||
|
let loc = self.ast.source_locs[node.index()];
|
||||||
|
|
||||||
let children = Children(ast.get_node_children(node));
|
let children = Children(self.ast.get_node_children(node));
|
||||||
let ty = self.ast.get_type_of_node(self.ip, &mut self.cache, node);
|
let ty = self.ast.get_type_of_node(self.ip, &mut self.cache, node);
|
||||||
let is_comptime =
|
let is_comptime = self
|
||||||
ast.is_node_comptime_evaluable(&mut self.comptime_cache, node);
|
.ast
|
||||||
_ = writeln_indented!(
|
.is_node_comptime_evaluable(&mut self.comptime_cache, node);
|
||||||
scopes.len() as u32 * 2,
|
writeln_indented!(
|
||||||
|
indent * 2,
|
||||||
w,
|
w,
|
||||||
"{node} {}({ty}) = ({loc}) {tag:?} {children}",
|
"{node} {}({ty}) = ({loc}) {tag:?} {children}",
|
||||||
if is_comptime { "CONST " } else { "" }
|
if is_comptime { "CONST " } else { "" }
|
||||||
);
|
)?;
|
||||||
});
|
|
||||||
|
for child in children.0 {
|
||||||
|
self.render_node(w, indent + 1, child)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn render<W: core::fmt::Write>(&mut self, w: &mut W) -> core::fmt::Result {
|
||||||
|
for file in self.ast.get_root_file_indices() {
|
||||||
|
self.render_node(w, 0, file)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2591,47 +2345,42 @@ pub mod ast_gen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// folds more AST-patterns into structures that are easier to build the IR with
|
|
||||||
pub fn fold_more_patterns(&mut self) {
|
|
||||||
use visitor::AstExt;
|
|
||||||
self.ast.visitor_mut().visit_post(|ast, _, i, tag, data| {
|
|
||||||
match tag {
|
|
||||||
// normalise functions with block-with-trailing-expr into block
|
|
||||||
Tag::FunctionDecl => {
|
|
||||||
let (_, block) = data.as_two_indices();
|
|
||||||
|
|
||||||
let (block_tag, block_data) =
|
|
||||||
ast.get_node_tag_and_data(block);
|
|
||||||
if block_tag == Tag::BlockTrailingExpr {
|
|
||||||
let (_, end) = block_data.as_extra_range();
|
|
||||||
let end = end - 1;
|
|
||||||
let expr = Index::new(ast.extra[end]);
|
|
||||||
let loc = ast.get_loc(expr);
|
|
||||||
let ret = ast.push_ret(Some(expr), loc);
|
|
||||||
// modify last element in place to be a return instruction
|
|
||||||
ast.extra[end] = *ret.as_u32();
|
|
||||||
ast.tags[block.index()] = Tag::Block;
|
|
||||||
eprintln!("folding ({block}): {block_tag:?} into Tag::Block");
|
|
||||||
eprintln!("expr: {expr:?}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn intern_types(&mut self) {
|
pub fn intern_types(&mut self) {
|
||||||
self.ast.visitor_mut().visit_post(|ast, _, i, tag, data| {
|
let mut nodes = self
|
||||||
|
.ast
|
||||||
|
.get_root_file_indices()
|
||||||
|
.map(|i| A::PushChildren(i))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
enum A {
|
||||||
|
PushChildren(Index),
|
||||||
|
PopSelf(Index),
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(node) = nodes.pop() {
|
||||||
|
match node {
|
||||||
|
A::PushChildren(i) => {
|
||||||
|
nodes.push(A::PopSelf(i));
|
||||||
|
nodes.extend(
|
||||||
|
self.ast
|
||||||
|
.get_node_children(i)
|
||||||
|
.into_iter()
|
||||||
|
.map(|i| A::PushChildren(i)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
A::PopSelf(i) => {
|
||||||
|
let tag = self.ast.tags[i.index()];
|
||||||
|
let data = self.ast.datas[i.index()];
|
||||||
match tag {
|
match tag {
|
||||||
Tag::ArrayType => {
|
Tag::ArrayType => {
|
||||||
let (length, pointee) = data.as_two_indices();
|
let (length, pointee) = data.as_two_indices();
|
||||||
let pointee =
|
let pointee =
|
||||||
ast.datas[pointee.index()].as_intern();
|
self.ast.datas[pointee.index()].as_intern();
|
||||||
variant!( self.intern.get_key(pointee) => intern::Key::PointerType { pointee, flags });
|
variant!( self.intern.get_key(pointee) => intern::Key::PointerType { pointee, flags });
|
||||||
|
|
||||||
// get interened value from constant node
|
// get interened value from constant node
|
||||||
let length = {
|
let length = {
|
||||||
let value = ast.datas[length.index()]
|
let value = self.ast.datas[length.index()]
|
||||||
.as_index_intern()
|
.as_index_intern()
|
||||||
.1;
|
.1;
|
||||||
|
|
||||||
|
@ -2664,48 +2413,48 @@ pub mod ast_gen {
|
||||||
Some(flags),
|
Some(flags),
|
||||||
length,
|
length,
|
||||||
);
|
);
|
||||||
ast.tags[i.index()] = Tag::InternedType;
|
self.ast.tags[i.index()] = Tag::InternedType;
|
||||||
ast.datas[i.index()] = Data::intern(ty);
|
self.ast.datas[i.index()] = Data::intern(ty);
|
||||||
}
|
}
|
||||||
Tag::PointerType => {
|
Tag::PointerType => {
|
||||||
let (pointee, flags) =
|
let (pointee, flags) =
|
||||||
data.as_index_and_extra_offset();
|
data.as_index_and_extra_offset();
|
||||||
let pointee =
|
let pointee =
|
||||||
ast.datas[pointee.index()].as_intern();
|
self.ast.datas[pointee.index()].as_intern();
|
||||||
let ty = self.intern.get_pointer_type(
|
let ty = self.intern.get_pointer_type(
|
||||||
pointee,
|
pointee,
|
||||||
Some(PointerFlags::unpack(flags as u8)),
|
Some(PointerFlags::unpack(flags as u8)),
|
||||||
);
|
);
|
||||||
ast.tags[i.index()] = Tag::InternedType;
|
self.ast.tags[i.index()] = Tag::InternedType;
|
||||||
ast.datas[i.index()] = Data::intern(ty);
|
self.ast.datas[i.index()] = Data::intern(ty);
|
||||||
}
|
}
|
||||||
Tag::TypeDeclRef => {
|
Tag::TypeDeclRef => {
|
||||||
let decl = data.as_index();
|
let decl = data.as_index();
|
||||||
let (name, _) = ast.datas[decl.index()]
|
let (name, _) = self.ast.datas[decl.index()]
|
||||||
.as_intern_and_extra_offset();
|
.as_intern_and_extra_offset();
|
||||||
|
|
||||||
let ty =
|
let ty =
|
||||||
self.intern.get_struct_type(name, decl);
|
self.intern.get_struct_type(name, decl);
|
||||||
ast.tags[i.index()] = Tag::InternedType;
|
self.ast.tags[i.index()] = Tag::InternedType;
|
||||||
ast.datas[i.index()] = Data::intern(ty);
|
self.ast.datas[i.index()] = Data::intern(ty);
|
||||||
}
|
}
|
||||||
Tag::FunctionProto => {
|
Tag::FunctionProto => {
|
||||||
let (_, i) = data.as_intern_and_extra_offset();
|
let (_, i) = data.as_intern_and_extra_offset();
|
||||||
let return_type = ast.get_type_of_node(
|
let return_type = self.ast.get_type_of_node(
|
||||||
&self.intern,
|
&self.intern,
|
||||||
&mut TypeCache::new(),
|
&mut TypeCache::new(),
|
||||||
Index::new(ast.extra[i]),
|
Index::new(self.ast.extra[i]),
|
||||||
);
|
);
|
||||||
let parameters = {
|
let parameters = {
|
||||||
let (a, b) = ast.datas
|
let (a, b) = self.ast.datas
|
||||||
[ast.extra[i + 1] as usize]
|
[self.ast.extra[i + 1] as usize]
|
||||||
.as_extra_range();
|
.as_extra_range();
|
||||||
ast.extra[a..b].iter().map(|&i| {
|
self.ast.extra[a..b].iter().map(|&i| {
|
||||||
// i is index to a parameter, a parameter is (index, intern)
|
// i is index to a parameter, a parameter is (index, intern)
|
||||||
let ty = ast.datas[i as usize]
|
let ty = self.ast.datas[i as usize]
|
||||||
.as_index_intern()
|
.as_index_intern()
|
||||||
.0;
|
.0;
|
||||||
ast.datas[ty.index()].as_intern()
|
self.ast.datas[ty.index()].as_intern()
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2716,7 +2465,7 @@ pub mod ast_gen {
|
||||||
let (name, offset) =
|
let (name, offset) =
|
||||||
data.as_intern_and_extra_offset();
|
data.as_intern_and_extra_offset();
|
||||||
let flags =
|
let flags =
|
||||||
StructFlags::unpack(ast.extra[offset]);
|
StructFlags::unpack(self.ast.extra[offset]);
|
||||||
|
|
||||||
let types = (offset + 1)
|
let types = (offset + 1)
|
||||||
..(offset + 1 + flags.num_fields as usize);
|
..(offset + 1 + flags.num_fields as usize);
|
||||||
|
@ -2726,13 +2475,13 @@ pub mod ast_gen {
|
||||||
+ 1
|
+ 1
|
||||||
+ flags.num_fields as usize * 2);
|
+ flags.num_fields as usize * 2);
|
||||||
|
|
||||||
let types = ast.extra[types]
|
let types = self.ast.extra[types]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&i| Index::new(i))
|
.map(|&i| Index::new(i))
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
ast.datas[i.index()].as_intern()
|
self.ast.datas[i.index()].as_intern()
|
||||||
});
|
});
|
||||||
let names = ast.extra[names]
|
let names = self.ast.extra[names]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&i| intern::Index::from_u32(i));
|
.map(|&i| intern::Index::from_u32(i));
|
||||||
|
|
||||||
|
@ -2746,42 +2495,65 @@ pub mod ast_gen {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_decl_refs(&mut self) {
|
pub fn resolve_decl_refs(&mut self) {
|
||||||
self.ast
|
let mut nodes =
|
||||||
.visitor_rev_mut()
|
self.ast.get_root_file_indices().collect::<Vec<_>>();
|
||||||
.visit_post(|ast, _, node, tag, _| {
|
let mut scopes = Vec::new();
|
||||||
match tag {
|
|
||||||
|
while let Some(node) = nodes.pop() {
|
||||||
|
match self.ast.tags[node.index()] {
|
||||||
|
Tag::File
|
||||||
|
| Tag::FunctionDecl
|
||||||
|
| Tag::Block
|
||||||
|
| Tag::BlockTrailingExpr => {
|
||||||
|
scopes.push(node);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let children = self.ast.get_node_children(node);
|
||||||
|
nodes.extend(children.into_iter().rev());
|
||||||
|
|
||||||
|
match self.ast.tags[node.index()] {
|
||||||
|
Tag::File
|
||||||
|
| Tag::FunctionDecl
|
||||||
|
| Tag::Block
|
||||||
|
| Tag::BlockTrailingExpr => {
|
||||||
|
scopes.pop();
|
||||||
|
}
|
||||||
Tag::TypeDeclRefUnresolved => {
|
Tag::TypeDeclRefUnresolved => {
|
||||||
let (scope, name) =
|
let (scope, name) =
|
||||||
ast.datas[node.index()].as_index_intern();
|
self.ast.datas[node.index()].as_index_intern();
|
||||||
// look in my_scope
|
// look in my_scope
|
||||||
if let Some(decl) = self.syms.find_type_symbol(
|
if let Some(decl) = self.syms.find_type_symbol(
|
||||||
scope,
|
scope,
|
||||||
name,
|
name,
|
||||||
ast.source_locs[node.index()],
|
self.ast.source_locs[node.index()],
|
||||||
) {
|
) {
|
||||||
ast.resolve_type_ref(node, decl)
|
self.ast.resolve_type_ref(node, decl)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Tag::DeclRefUnresolved => {
|
Tag::DeclRefUnresolved => {
|
||||||
let (scope, name) =
|
let (scope, name) =
|
||||||
ast.datas[node.index()].as_index_intern();
|
self.ast.datas[node.index()].as_index_intern();
|
||||||
|
|
||||||
// look in my_scope
|
// look in my_scope
|
||||||
if let Some(decl) = self.syms.find_symbol(
|
if let Some(decl) = self.syms.find_symbol(
|
||||||
scope,
|
scope,
|
||||||
name,
|
name,
|
||||||
ast.source_locs[node.index()],
|
self.ast.source_locs[node.index()],
|
||||||
) {
|
) {
|
||||||
ast.resolve_decl_ref(node, decl)
|
self.ast.resolve_decl_ref(node, decl)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_scope(&self) -> Index {
|
fn current_scope(&self) -> Index {
|
||||||
|
@ -4113,22 +3885,12 @@ pub mod ast_gen {
|
||||||
loc: tokens.current_source_location(),
|
loc: tokens.current_source_location(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let decl = self.ast.reserve_node();
|
|
||||||
let decl = self.parse_braced(tokens, |this, tokens| {
|
let decl = self.parse_braced(tokens, |this, tokens| {
|
||||||
this.parse_struct_fields(tokens).map(|fields| {
|
this.parse_struct_fields(tokens).map(|fields| {
|
||||||
_ = tokens.eat_token(Token::Comma);
|
_ = tokens.eat_token(Token::Comma);
|
||||||
let flags =
|
let flags =
|
||||||
StructFlags::new(packed, c_like, fields.len() as u32);
|
StructFlags::new(packed, c_like, fields.len() as u32);
|
||||||
|
this.ast.push_struct_decl(name, flags, fields, loc)
|
||||||
this.intern.insert_or_replace_struct_type(
|
|
||||||
name,
|
|
||||||
decl,
|
|
||||||
flags.packed,
|
|
||||||
flags.c_like,
|
|
||||||
vec![],
|
|
||||||
);
|
|
||||||
|
|
||||||
this.ast.set_struct_decl(decl, name, flags, fields, loc)
|
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -4426,7 +4188,6 @@ pub mod ast_gen {
|
||||||
self.create_comptime_folding_graph(intern::AMD64_POINTER_BITS);
|
self.create_comptime_folding_graph(intern::AMD64_POINTER_BITS);
|
||||||
eprintln!("interning types:");
|
eprintln!("interning types:");
|
||||||
self.intern_types();
|
self.intern_types();
|
||||||
self.fold_more_patterns();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_scope(&mut self, ast: Index, name: intern::Index) {
|
fn push_scope(&mut self, ast: Index, name: intern::Index) {
|
||||||
|
@ -4502,15 +4263,10 @@ pub mod ast_gen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod irgen {
|
pub mod ir_gen {
|
||||||
|
|
||||||
use super::visitor::AstExt;
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{symbol_table::syms2::Symbols, triples::*};
|
||||||
symbol_table::syms2::Symbols,
|
|
||||||
triples::{self, *},
|
|
||||||
};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
struct IRGen {
|
struct IRGen {
|
||||||
ast: Ast,
|
ast: Ast,
|
||||||
|
@ -4519,143 +4275,5 @@ pub mod irgen {
|
||||||
ip: intern::InternPool,
|
ip: intern::InternPool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IRGen {
|
impl IRGen {}
|
||||||
fn build(&mut self) {
|
|
||||||
let mut mapping = HashMap::<Index, u32>::new();
|
|
||||||
self.ast.visitor().visit(
|
|
||||||
|ast, scopes, i, tag, data| {
|
|
||||||
// pre
|
|
||||||
match tag {
|
|
||||||
Tag::Root => todo!(),
|
|
||||||
Tag::File => todo!(),
|
|
||||||
Tag::FunctionProto => todo!(),
|
|
||||||
Tag::FunctionDecl => todo!(),
|
|
||||||
Tag::ParameterList => todo!(),
|
|
||||||
Tag::Parameter => todo!(),
|
|
||||||
Tag::Block => todo!(),
|
|
||||||
Tag::BlockTrailingExpr => todo!(),
|
|
||||||
Tag::Constant => todo!(),
|
|
||||||
Tag::ExprStmt => todo!(),
|
|
||||||
Tag::ReturnStmt => todo!(),
|
|
||||||
Tag::ReturnExprStmt => todo!(),
|
|
||||||
Tag::VarDecl => todo!(),
|
|
||||||
Tag::MutVarDecl => todo!(),
|
|
||||||
Tag::VarDeclAssignment => todo!(),
|
|
||||||
Tag::MutVarDeclAssignment => todo!(),
|
|
||||||
Tag::GlobalDecl => todo!(),
|
|
||||||
Tag::StructDecl => todo!(),
|
|
||||||
Tag::FieldDecl => todo!(),
|
|
||||||
Tag::DeclRef => todo!(),
|
|
||||||
Tag::DeclRefUnresolved => todo!(),
|
|
||||||
Tag::InternedType => todo!(),
|
|
||||||
Tag::TypeDeclRef => todo!(),
|
|
||||||
Tag::TypeDeclRefUnresolved => todo!(),
|
|
||||||
Tag::PointerType => todo!(),
|
|
||||||
Tag::ArrayType => todo!(),
|
|
||||||
Tag::CallExpr => todo!(),
|
|
||||||
Tag::FieldAccess => todo!(),
|
|
||||||
Tag::ArgumentList => todo!(),
|
|
||||||
Tag::Argument => todo!(),
|
|
||||||
Tag::NamedArgument => todo!(),
|
|
||||||
Tag::ExplicitCast => todo!(),
|
|
||||||
Tag::Deref => todo!(),
|
|
||||||
Tag::AddressOf => todo!(),
|
|
||||||
Tag::Not => todo!(),
|
|
||||||
Tag::Negate => todo!(),
|
|
||||||
Tag::Or => todo!(),
|
|
||||||
Tag::And => todo!(),
|
|
||||||
Tag::BitOr => todo!(),
|
|
||||||
Tag::BitXOr => todo!(),
|
|
||||||
Tag::BitAnd => todo!(),
|
|
||||||
Tag::Eq => todo!(),
|
|
||||||
Tag::NEq => todo!(),
|
|
||||||
Tag::Lt => todo!(),
|
|
||||||
Tag::Gt => todo!(),
|
|
||||||
Tag::Le => todo!(),
|
|
||||||
Tag::Ge => todo!(),
|
|
||||||
Tag::Shl => todo!(),
|
|
||||||
Tag::Shr => todo!(),
|
|
||||||
Tag::Add => todo!(),
|
|
||||||
Tag::Sub => todo!(),
|
|
||||||
Tag::Mul => todo!(),
|
|
||||||
Tag::Div => todo!(),
|
|
||||||
Tag::Rem => todo!(),
|
|
||||||
Tag::Assign => todo!(),
|
|
||||||
Tag::SubscriptExpr => todo!(),
|
|
||||||
Tag::IfExpr => todo!(),
|
|
||||||
Tag::IfElseExpr => todo!(),
|
|
||||||
Tag::Error => todo!(),
|
|
||||||
Tag::Undefined => todo!(),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|ast, scopes, i, tag, data| {
|
|
||||||
// post
|
|
||||||
match tag {
|
|
||||||
Tag::Root => todo!(),
|
|
||||||
Tag::File => todo!(),
|
|
||||||
Tag::FunctionProto => todo!(),
|
|
||||||
Tag::FunctionDecl => {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
Tag::ParameterList => todo!(),
|
|
||||||
Tag::Parameter => todo!(),
|
|
||||||
Tag::Block => todo!(),
|
|
||||||
Tag::BlockTrailingExpr => todo!(),
|
|
||||||
Tag::Constant => todo!(),
|
|
||||||
Tag::ExprStmt => todo!(),
|
|
||||||
Tag::ReturnStmt => todo!(),
|
|
||||||
Tag::ReturnExprStmt => todo!(),
|
|
||||||
Tag::VarDecl => todo!(),
|
|
||||||
Tag::MutVarDecl => todo!(),
|
|
||||||
Tag::VarDeclAssignment => todo!(),
|
|
||||||
Tag::MutVarDeclAssignment => todo!(),
|
|
||||||
Tag::GlobalDecl => todo!(),
|
|
||||||
Tag::StructDecl => todo!(),
|
|
||||||
Tag::FieldDecl => todo!(),
|
|
||||||
Tag::DeclRef => todo!(),
|
|
||||||
Tag::DeclRefUnresolved => todo!(),
|
|
||||||
Tag::InternedType => todo!(),
|
|
||||||
Tag::TypeDeclRef => todo!(),
|
|
||||||
Tag::TypeDeclRefUnresolved => todo!(),
|
|
||||||
Tag::PointerType => todo!(),
|
|
||||||
Tag::ArrayType => todo!(),
|
|
||||||
Tag::CallExpr => todo!(),
|
|
||||||
Tag::FieldAccess => todo!(),
|
|
||||||
Tag::ArgumentList => todo!(),
|
|
||||||
Tag::Argument => todo!(),
|
|
||||||
Tag::NamedArgument => todo!(),
|
|
||||||
Tag::ExplicitCast => todo!(),
|
|
||||||
Tag::Deref => todo!(),
|
|
||||||
Tag::AddressOf => todo!(),
|
|
||||||
Tag::Not => todo!(),
|
|
||||||
Tag::Negate => todo!(),
|
|
||||||
Tag::Or => todo!(),
|
|
||||||
Tag::And => todo!(),
|
|
||||||
Tag::BitOr => todo!(),
|
|
||||||
Tag::BitXOr => todo!(),
|
|
||||||
Tag::BitAnd => todo!(),
|
|
||||||
Tag::Eq => todo!(),
|
|
||||||
Tag::NEq => todo!(),
|
|
||||||
Tag::Lt => todo!(),
|
|
||||||
Tag::Gt => todo!(),
|
|
||||||
Tag::Le => todo!(),
|
|
||||||
Tag::Ge => todo!(),
|
|
||||||
Tag::Shl => todo!(),
|
|
||||||
Tag::Shr => todo!(),
|
|
||||||
Tag::Add => todo!(),
|
|
||||||
Tag::Sub => todo!(),
|
|
||||||
Tag::Mul => todo!(),
|
|
||||||
Tag::Div => todo!(),
|
|
||||||
Tag::Rem => todo!(),
|
|
||||||
Tag::Assign => todo!(),
|
|
||||||
Tag::SubscriptExpr => todo!(),
|
|
||||||
Tag::IfExpr => todo!(),
|
|
||||||
Tag::IfElseExpr => todo!(),
|
|
||||||
Tag::Error => todo!(),
|
|
||||||
Tag::Undefined => todo!(),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,36 +237,36 @@ impl Inst {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Data {
|
struct Data {
|
||||||
lhs: u32,
|
lhs: u32,
|
||||||
rhs: u32,
|
rhs: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Data {
|
impl Data {
|
||||||
pub fn new(lhs: u32, rhs: u32) -> Self {
|
fn new(lhs: u32, rhs: u32) -> Self {
|
||||||
Self { lhs, rhs }
|
Self { lhs, rhs }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lhs(lhs: u32) -> Data {
|
fn lhs(lhs: u32) -> Data {
|
||||||
Self { lhs, rhs: 0 }
|
Self { lhs, rhs: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_u32(&self) -> u32 {
|
fn as_u32(&self) -> u32 {
|
||||||
self.lhs
|
self.lhs
|
||||||
}
|
}
|
||||||
pub fn as_u64(&self) -> u64 {
|
fn as_u64(&self) -> u64 {
|
||||||
self.lhs as u64 | (self.rhs as u64) << u32::BITS as u64
|
self.lhs as u64 | (self.rhs as u64) << u32::BITS as u64
|
||||||
}
|
}
|
||||||
pub fn as_index(&self) -> intern::Index {
|
fn as_index(&self) -> intern::Index {
|
||||||
intern::Index::from_u32(self.lhs)
|
intern::Index::from_u32(self.lhs)
|
||||||
}
|
}
|
||||||
pub fn as_index_index(&self) -> (intern::Index, intern::Index) {
|
fn as_index_index(&self) -> (intern::Index, intern::Index) {
|
||||||
(
|
(
|
||||||
intern::Index::from_u32(self.lhs),
|
intern::Index::from_u32(self.lhs),
|
||||||
intern::Index::from_u32(self.rhs),
|
intern::Index::from_u32(self.rhs),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
pub fn as_lhs_rhs(&self) -> (u32, u32) {
|
fn as_lhs_rhs(&self) -> (u32, u32) {
|
||||||
(self.lhs, self.rhs)
|
(self.lhs, self.rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -838,7 +838,7 @@ impl IR {
|
||||||
data: Vec::new(),
|
data: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn push(&mut self, inst: Inst, data: Option<Data>) -> u32 {
|
fn push(&mut self, inst: Inst, data: Option<Data>) -> u32 {
|
||||||
let node = self.nodes.len() as u32;
|
let node = self.nodes.len() as u32;
|
||||||
self.nodes.push(inst);
|
self.nodes.push(inst);
|
||||||
self.data.push(data);
|
self.data.push(data);
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
fn main() -> u32 {
|
|
||||||
let a: u10 = 16u10;
|
|
||||||
let b: u80 = 299;
|
|
||||||
|
|
||||||
return a as u32 + b as u32;
|
|
||||||
}
|
|
Loading…
Reference in a new issue