Compare commits

...

7 commits

Author SHA1 Message Date
Janis 43c828d96f irgen of ast2 2024-12-29 19:57:29 +01:00
Janis f6b956deee normalising BlockTrailingExpr where it returns into Block with a Ret expr 2024-12-27 03:49:50 +01:00
Janis e002a6ddc9 small fixes/visiter pattern/pub visibility 2024-12-27 03:49:25 +01:00
Janis 1b5cc3302b rename ast_visitor module to visitor 2024-12-26 01:03:30 +01:00
Janis f6fc83ce02 using visitor for rendering ast 2024-12-26 01:02:40 +01:00
Janis 4e59e02178 visitor pattern for ast 2024-12-26 00:40:11 +01:00
Janis 13df06421c intern struct type the first time it is defined
at that point the fields might not yet have proper types
2024-12-25 20:37:35 +01:00
5 changed files with 537 additions and 146 deletions

4
Makefile Normal file
View file

@ -0,0 +1,4 @@
test:
cargo run --bin main -- -i tests/legal/call.sea asm > asm.S
clang asm.S -c && clang asm.o -o asm && ./asm; echo $$?

View file

@ -2,7 +2,6 @@ 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};
@ -379,7 +378,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())
} }
} }
@ -490,7 +489,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: "<this string is empty>" }, EMPTY_STRING => Key::String { str: "" },
EMPTY_BYTES => Key::Bytes { bytes: &[] }, EMPTY_BYTES => Key::Bytes { bytes: &[] },
); );

View file

@ -977,6 +977,17 @@ 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()
@ -1265,7 +1276,10 @@ impl Ast {
{ {
return_type return_type
} else { } else {
eprintln!("lhs of call expr is not a function!"); eprintln!(
"lhs of call expr is not a function: {fn_ty}: {:?}",
ip.get_key(fn_ty)
);
void void
} }
} }
@ -2075,6 +2089,254 @@ 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)]
@ -2128,37 +2390,21 @@ impl<'a> AstRenderer<'a> {
} }
} }
fn render_node<W: core::fmt::Write>( fn render<W: core::fmt::Write>(&mut self, w: &mut W) -> core::fmt::Result {
&mut self, self.ast.visitor().visit_pre(|ast, scopes, node, tag, _| {
w: &mut W, let loc = ast.source_locs[node.index()];
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(self.ast.get_node_children(node)); let children = Children(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 = self let is_comptime =
.ast ast.is_node_comptime_evaluable(&mut self.comptime_cache, node);
.is_node_comptime_evaluable(&mut self.comptime_cache, node); _ = writeln_indented!(
writeln_indented!( scopes.len() as u32 * 2,
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(())
} }
@ -2345,42 +2591,47 @@ 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) {
let mut nodes = self self.ast.visitor_mut().visit_post(|ast, _, i, tag, data| {
.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 =
self.ast.datas[pointee.index()].as_intern(); 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 = self.ast.datas[length.index()] let value = ast.datas[length.index()]
.as_index_intern() .as_index_intern()
.1; .1;
@ -2413,48 +2664,48 @@ pub mod ast_gen {
Some(flags), Some(flags),
length, length,
); );
self.ast.tags[i.index()] = Tag::InternedType; ast.tags[i.index()] = Tag::InternedType;
self.ast.datas[i.index()] = Data::intern(ty); 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 =
self.ast.datas[pointee.index()].as_intern(); 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)),
); );
self.ast.tags[i.index()] = Tag::InternedType; ast.tags[i.index()] = Tag::InternedType;
self.ast.datas[i.index()] = Data::intern(ty); ast.datas[i.index()] = Data::intern(ty);
} }
Tag::TypeDeclRef => { Tag::TypeDeclRef => {
let decl = data.as_index(); let decl = data.as_index();
let (name, _) = self.ast.datas[decl.index()] let (name, _) = 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);
self.ast.tags[i.index()] = Tag::InternedType; ast.tags[i.index()] = Tag::InternedType;
self.ast.datas[i.index()] = Data::intern(ty); 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 = self.ast.get_type_of_node( let return_type = ast.get_type_of_node(
&self.intern, &self.intern,
&mut TypeCache::new(), &mut TypeCache::new(),
Index::new(self.ast.extra[i]), Index::new(ast.extra[i]),
); );
let parameters = { let parameters = {
let (a, b) = self.ast.datas let (a, b) = ast.datas
[self.ast.extra[i + 1] as usize] [ast.extra[i + 1] as usize]
.as_extra_range(); .as_extra_range();
self.ast.extra[a..b].iter().map(|&i| { 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 = self.ast.datas[i as usize] let ty = ast.datas[i as usize]
.as_index_intern() .as_index_intern()
.0; .0;
self.ast.datas[ty.index()].as_intern() ast.datas[ty.index()].as_intern()
}) })
}; };
@ -2465,7 +2716,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(self.ast.extra[offset]); StructFlags::unpack(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);
@ -2475,13 +2726,13 @@ pub mod ast_gen {
+ 1 + 1
+ flags.num_fields as usize * 2); + flags.num_fields as usize * 2);
let types = self.ast.extra[types] let types = ast.extra[types]
.iter() .iter()
.map(|&i| Index::new(i)) .map(|&i| Index::new(i))
.map(|i| { .map(|i| {
self.ast.datas[i.index()].as_intern() ast.datas[i.index()].as_intern()
}); });
let names = self.ast.extra[names] let names = ast.extra[names]
.iter() .iter()
.map(|&i| intern::Index::from_u32(i)); .map(|&i| intern::Index::from_u32(i));
@ -2495,65 +2746,42 @@ pub mod ast_gen {
} }
_ => {} _ => {}
} }
} });
}
}
} }
pub fn resolve_decl_refs(&mut self) { pub fn resolve_decl_refs(&mut self) {
let mut nodes = self.ast
self.ast.get_root_file_indices().collect::<Vec<_>>(); .visitor_rev_mut()
let mut scopes = Vec::new(); .visit_post(|ast, _, node, tag, _| {
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) =
self.ast.datas[node.index()].as_index_intern(); 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,
self.ast.source_locs[node.index()], ast.source_locs[node.index()],
) { ) {
self.ast.resolve_type_ref(node, decl) ast.resolve_type_ref(node, decl)
}; };
} }
Tag::DeclRefUnresolved => { Tag::DeclRefUnresolved => {
let (scope, name) = let (scope, name) =
self.ast.datas[node.index()].as_index_intern(); 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,
self.ast.source_locs[node.index()], ast.source_locs[node.index()],
) { ) {
self.ast.resolve_decl_ref(node, decl) ast.resolve_decl_ref(node, decl)
}; };
} }
_ => {} _ => {}
} }
} });
} }
fn current_scope(&self) -> Index { fn current_scope(&self) -> Index {
@ -3885,12 +4113,22 @@ 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)
}) })
})?; })?;
@ -4188,6 +4426,7 @@ 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) {
@ -4263,10 +4502,15 @@ pub mod ast_gen {
} }
} }
pub mod ir_gen { pub mod irgen {
use super::visitor::AstExt;
use super::*; use super::*;
use crate::{symbol_table::syms2::Symbols, triples::*}; use crate::{
symbol_table::syms2::Symbols,
triples::{self, *},
};
use std::collections::HashMap;
struct IRGen { struct IRGen {
ast: Ast, ast: Ast,
@ -4275,5 +4519,143 @@ pub mod ir_gen {
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!(),
}
},
);
}
}
} }

View file

@ -237,36 +237,36 @@ impl Inst {
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
struct Data { pub struct Data {
lhs: u32, lhs: u32,
rhs: u32, rhs: u32,
} }
impl Data { impl Data {
fn new(lhs: u32, rhs: u32) -> Self { pub fn new(lhs: u32, rhs: u32) -> Self {
Self { lhs, rhs } Self { lhs, rhs }
} }
fn lhs(lhs: u32) -> Data { pub fn lhs(lhs: u32) -> Data {
Self { lhs, rhs: 0 } Self { lhs, rhs: 0 }
} }
fn as_u32(&self) -> u32 { pub fn as_u32(&self) -> u32 {
self.lhs self.lhs
} }
fn as_u64(&self) -> u64 { pub 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
} }
fn as_index(&self) -> intern::Index { pub fn as_index(&self) -> intern::Index {
intern::Index::from_u32(self.lhs) intern::Index::from_u32(self.lhs)
} }
fn as_index_index(&self) -> (intern::Index, intern::Index) { pub 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),
) )
} }
fn as_lhs_rhs(&self) -> (u32, u32) { pub 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(),
} }
} }
fn push(&mut self, inst: Inst, data: Option<Data>) -> u32 { pub 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);

View file

@ -0,0 +1,6 @@
fn main() -> u32 {
let a: u10 = 16u10;
let b: u80 = 299;
return a as u32 + b as u32;
}