mirror of
https://github.com/Noratrieb/uwucc.git
synced 2026-01-17 01:55:07 +01:00
a bunch of stuff mostly
This commit is contained in:
parent
56e7f77a0d
commit
b9a2f939c4
29 changed files with 734 additions and 345 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
|
@ -34,7 +34,6 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"lasso",
|
|
||||||
"parser",
|
"parser",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
]
|
]
|
||||||
|
|
@ -318,6 +317,7 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"dbg-pls",
|
"dbg-pls",
|
||||||
"insta",
|
"insta",
|
||||||
|
"lasso",
|
||||||
"peekmore",
|
"peekmore",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -573,6 +573,8 @@ checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||||
name = "uwucc"
|
name = "uwucc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"analysis",
|
||||||
|
"dbg-pls",
|
||||||
"parser",
|
"parser",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,6 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
analysis = { path = "./analysis" }
|
||||||
parser = { path = "./parser" }
|
parser = { path = "./parser" }
|
||||||
|
dbg-pls = { version = "0.3.2", features = ["derive", "colors"] }
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,5 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bumpalo = "3.10.0"
|
bumpalo = "3.10.0"
|
||||||
indexmap = "1.9.1"
|
indexmap = "1.9.1"
|
||||||
lasso = "0.6.0"
|
|
||||||
parser = { path = "../parser" }
|
parser = { path = "../parser" }
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
|
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
use indexmap::IndexMap;
|
|
||||||
use lasso::Spur;
|
|
||||||
use parser::Spanned;
|
|
||||||
|
|
||||||
pub type Symbol = Spur;
|
|
||||||
|
|
||||||
pub type Ident = Spanned<Symbol>;
|
|
||||||
|
|
||||||
pub struct Hir<'hir> {
|
|
||||||
defs: Vec<Def>,
|
|
||||||
__: &'hir (),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub struct DefId(u32);
|
|
||||||
|
|
||||||
pub enum IntTySignedness {
|
|
||||||
Signed,
|
|
||||||
Unsigned,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for IntTySignedness {
|
|
||||||
fn default() -> Self {
|
|
||||||
// C defaults to unsigned for integers.
|
|
||||||
Self::Signed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum IntTyKind {
|
|
||||||
Short,
|
|
||||||
Int,
|
|
||||||
Long,
|
|
||||||
LongLong,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct IntTy {
|
|
||||||
pub sign: IntTySignedness,
|
|
||||||
pub kind: IntTyKind,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Def {
|
|
||||||
pub name: Ident,
|
|
||||||
pub def_id: DefId,
|
|
||||||
pub kind: DefKind,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum DefKind {
|
|
||||||
Union(UnionTy),
|
|
||||||
Enum(EnumTy),
|
|
||||||
Struct(StructTy),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct UnionTy {
|
|
||||||
pub def_id: DefId,
|
|
||||||
pub variants: IndexMap<Symbol, Ty>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct StructTy {
|
|
||||||
pub def_id: DefId,
|
|
||||||
pub fields: IndexMap<Symbol, Ty>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct EnumTy {
|
|
||||||
pub def_id: DefId,
|
|
||||||
pub variants: IndexMap<Symbol, i128>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum TyKind {
|
|
||||||
Void,
|
|
||||||
Char,
|
|
||||||
SChar,
|
|
||||||
UChar,
|
|
||||||
Integer(IntTy),
|
|
||||||
Float,
|
|
||||||
Double,
|
|
||||||
LongDouble,
|
|
||||||
Bool,
|
|
||||||
Union(UnionTy),
|
|
||||||
Struct(StructTy),
|
|
||||||
Enum(EnumTy),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Ty {
|
|
||||||
kind: TyKind,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum NodeKind {
|
|
||||||
FunctionDef(FunctionDef),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ExternalDecl;
|
|
||||||
|
|
||||||
pub struct FunctionDef {
|
|
||||||
name: Symbol,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Expr<'hir> {
|
|
||||||
kind: ExprKind<'hir>,
|
|
||||||
ty: Ty,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ExprKind<'hir> {
|
|
||||||
Var(DefId),
|
|
||||||
Binary(BinaryOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
|
|
||||||
Unary(UnaryOp, &'hir Expr<'hir>),
|
|
||||||
Cast(CastExpr<'hir>),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CastExpr<'hir> {
|
|
||||||
from: Ty,
|
|
||||||
to: Ty,
|
|
||||||
expr: &'hir Expr<'hir>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum UnaryOp {
|
|
||||||
AddrOf,
|
|
||||||
Deref,
|
|
||||||
Plus,
|
|
||||||
Minus,
|
|
||||||
Tilde,
|
|
||||||
Bang,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ArithOpKind {
|
|
||||||
Mul,
|
|
||||||
Div,
|
|
||||||
Mod,
|
|
||||||
Add,
|
|
||||||
Sub,
|
|
||||||
Shl,
|
|
||||||
Shr,
|
|
||||||
BitAnd,
|
|
||||||
BitXor,
|
|
||||||
BitOr,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ComparisonKind {
|
|
||||||
Lt,
|
|
||||||
Gt,
|
|
||||||
LtEq,
|
|
||||||
GtEq,
|
|
||||||
Eq,
|
|
||||||
Neq,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum BinaryOp {
|
|
||||||
Arith(ArithOpKind),
|
|
||||||
LogicalAnd,
|
|
||||||
LogicalOr,
|
|
||||||
Comparison(ComparisonKind),
|
|
||||||
Comma,
|
|
||||||
Index, // lhs[rhs]
|
|
||||||
Assign(Option<ArithOpKind>),
|
|
||||||
}
|
|
||||||
|
|
@ -5,53 +5,131 @@
|
||||||
/// ```c
|
/// ```c
|
||||||
/// int i = 0;
|
/// int i = 0;
|
||||||
/// long l = 1;
|
/// long l = 1;
|
||||||
/// int y = ((int)&i)+l;
|
/// if (true) {
|
||||||
|
/// i = 1;
|
||||||
|
/// } else {
|
||||||
|
/// i = 2;
|
||||||
|
/// }
|
||||||
|
/// yeet(i);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```c
|
/// ```c
|
||||||
/// int _0; // i
|
/// bb0:
|
||||||
/// long _1; // l
|
/// %0 = alloca 4, 4
|
||||||
/// int *_2; // tmp &i
|
/// store _0, 0
|
||||||
/// int _3; // tmp (int)&i
|
/// %1 = alloca 8, 8
|
||||||
/// int _4; // tmp l (implicit cast to int)
|
/// store %1, 1
|
||||||
/// int _5; // y
|
/// branch true, bb1, bb2
|
||||||
///
|
/// bb1:
|
||||||
/// _0 = Const(0)
|
/// store %0, 1
|
||||||
/// _1 = Const(1)
|
/// branch bb3
|
||||||
/// _2 = AddrOf(_0)
|
/// bb2:
|
||||||
/// _3 = Cast(Ptr, Int, _2)
|
/// store %0, 2
|
||||||
/// _4 = Cast(Long, Int, _1)
|
/// branch bb3
|
||||||
/// _5 = _3 + _4
|
/// bb3:
|
||||||
|
/// %val = load %0
|
||||||
|
/// call yeet(%val)
|
||||||
/// ```
|
/// ```
|
||||||
|
use parser::{Span, Symbol};
|
||||||
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use parser::Span;
|
use crate::ty::Ty;
|
||||||
|
|
||||||
use crate::hir::Ty;
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct DefId(u32);
|
||||||
|
|
||||||
struct Body {
|
#[derive(Debug, Clone)]
|
||||||
locals: Vec<LocalDecl>,
|
pub struct Layout {
|
||||||
statements: Vec<Statement>,
|
pub size: u64,
|
||||||
|
pub align: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LocalDecl {
|
pub struct Ir {
|
||||||
pub ty: Ty,
|
pub funcs: FxHashMap<DefId, Func>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Statement {
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Func {
|
||||||
|
pub bbs: Vec<BasicBlock>,
|
||||||
|
pub def_span: Span,
|
||||||
|
pub ret_ty: Ty,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct BasicBlock {
|
||||||
|
pub regs: Vec<RegisterData>,
|
||||||
|
pub statements: Vec<Statement>,
|
||||||
|
pub term: Branch,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct RegisterData {
|
||||||
|
pub name: Option<Symbol>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub struct Register(pub u32);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Statement {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub kind: StatementKind,
|
pub kind: StatementKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum StatementKind {
|
#[derive(Debug, Clone)]
|
||||||
Assign(LValue, RValue),
|
pub enum StatementKind {
|
||||||
|
Alloca {
|
||||||
|
reg: Register,
|
||||||
|
size: Operand,
|
||||||
|
align: Operand,
|
||||||
|
},
|
||||||
|
Store {
|
||||||
|
ptr_reg: Register,
|
||||||
|
size: Operand,
|
||||||
|
align: Operand,
|
||||||
|
},
|
||||||
|
Load {
|
||||||
|
result: Register,
|
||||||
|
ptr_reg: Register,
|
||||||
|
size: Operand,
|
||||||
|
align: Operand,
|
||||||
|
},
|
||||||
|
Arith {
|
||||||
|
kind: ArithKind,
|
||||||
|
lhs: Register,
|
||||||
|
rhs: Register,
|
||||||
|
result: Register,
|
||||||
|
},
|
||||||
|
Comp {
|
||||||
|
kind: CompKind,
|
||||||
|
lhs: Register,
|
||||||
|
rhs: Register,
|
||||||
|
result: Register,
|
||||||
|
},
|
||||||
|
PtrOffset {
|
||||||
|
reg: Register,
|
||||||
|
amount: Operand,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RValue {
|
#[derive(Debug, Clone)]
|
||||||
BinOp(BinOpKind, Operand),
|
pub enum Operand {
|
||||||
Const,
|
Reg(Register),
|
||||||
|
Const(ConstValue),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BinOpKind {
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Branch {
|
||||||
|
Goto(u32),
|
||||||
|
Switch {
|
||||||
|
cond: Option<RValue>,
|
||||||
|
yes: u32,
|
||||||
|
no: u32,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum ArithKind {
|
||||||
Add,
|
Add,
|
||||||
Sub,
|
Sub,
|
||||||
Mul,
|
Mul,
|
||||||
|
|
@ -59,8 +137,35 @@ enum BinOpKind {
|
||||||
Mod,
|
Mod,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Operand {
|
#[derive(Debug, Clone)]
|
||||||
Local(usize),
|
pub enum CompKind {
|
||||||
|
Eq,
|
||||||
|
Neq,
|
||||||
|
Gt,
|
||||||
|
Geq,
|
||||||
|
Lt,
|
||||||
|
Leq,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LValue {}
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum RValue {
|
||||||
|
Register(u32),
|
||||||
|
Constant(ConstValue),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum ConstValue {
|
||||||
|
Int(u128),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Layout {
|
||||||
|
pub fn size_align(size: u64, align: u64) -> Self {
|
||||||
|
Self { size, align }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConstValue {
|
||||||
|
pub fn u64(int: u64) -> Self {
|
||||||
|
Self::Int(int.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,20 @@
|
||||||
#![allow(dead_code)] // TODO: no
|
#![allow(dead_code)] // TODO: no
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
|
|
||||||
mod hir;
|
|
||||||
mod ir;
|
mod ir;
|
||||||
mod lower;
|
mod lower;
|
||||||
|
mod ty;
|
||||||
|
|
||||||
|
pub use lower::lower_translation_unit;
|
||||||
|
use parser::Span;
|
||||||
|
|
||||||
|
pub struct Error {
|
||||||
|
msg: String,
|
||||||
|
span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
pub fn new(msg: String, span: Span) -> Self {
|
||||||
|
Self { msg, span }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,85 +1,180 @@
|
||||||
use parser::{ast, Span};
|
use parser::{
|
||||||
|
ast::{DeclAttr, ExternalDecl, Stmt, TranslationUnit, TypeSpecifier},
|
||||||
|
Span, Symbol,
|
||||||
|
};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::hir::{self, DefId, Symbol};
|
use crate::{
|
||||||
|
ir::{
|
||||||
|
BasicBlock, Branch, ConstValue, Func, Ir, Layout, Operand, Register, RegisterData,
|
||||||
|
Statement, StatementKind,
|
||||||
|
},
|
||||||
|
ty::Ty,
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct LowerCtx<'hir> {
|
struct LoweringCx {}
|
||||||
hir_symbol_intern: lasso::Rodeo,
|
|
||||||
hir_arena: &'hir bumpalo::Bump,
|
|
||||||
global_symbols: FxHashMap<Symbol, &'hir hir::ExternalDecl>,
|
|
||||||
scope: Scope,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Scope {
|
pub fn lower_translation_unit(ast: &TranslationUnit) -> Result<Ir, Error> {
|
||||||
parent: Option<Box<Scope>>,
|
let mut lcx = LoweringCx {};
|
||||||
variables: FxHashMap<Symbol, DefId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Scope {
|
for (decl, _) in ast {
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
parent: None,
|
|
||||||
variables: FxHashMap::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert(&mut self, symbol: Symbol, def_id: DefId) {
|
|
||||||
self.variables.insert(symbol, def_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enter_new(&mut self) {
|
|
||||||
let new = Self::new();
|
|
||||||
let this = std::mem::replace(self, new);
|
|
||||||
self.parent = Some(Box::new(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn leave(&mut self) {
|
|
||||||
let old = std::mem::replace(self, Self::new());
|
|
||||||
let parent = old.parent.expect("parent not found when leaving scope");
|
|
||||||
*self = *parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lookup(&self, sym: Symbol) -> Option<DefId> {
|
|
||||||
self.variables
|
|
||||||
.get(&sym)
|
|
||||||
.copied()
|
|
||||||
.or_else(|| self.parent.as_ref().and_then(|parent| parent.lookup(sym)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'hir> LowerCtx<'hir> {
|
|
||||||
pub fn lower_translation_unit(&mut self, unit: &ast::TranslationUnit) -> hir::Hir<'hir> {
|
|
||||||
for _decl in unit {}
|
|
||||||
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lower_decl(&mut self, decl: &ast::ExternalDecl, span: Span) -> hir::ExternalDecl {
|
|
||||||
match decl {
|
match decl {
|
||||||
ast::ExternalDecl::Decl(_) => todo!(),
|
ExternalDecl::Decl(_) => todo!("decl is unsupported"),
|
||||||
ast::ExternalDecl::FunctionDef(def) => {
|
ExternalDecl::FunctionDef(def) => {
|
||||||
let _fn_def = self.lower_function_def(def, span);
|
|
||||||
hir::ExternalDecl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lower_function_def(&mut self, def: &ast::FunctionDef, _span: Span) -> hir::FunctionDef {
|
|
||||||
let decl = def.decl.uwnrap_normal();
|
let decl = def.decl.uwnrap_normal();
|
||||||
let (init_declarator, _declarator_span) = decl
|
let body = &def.body;
|
||||||
.init_declarators
|
let ret_ty = lower_ty(&decl.decl_spec.ty);
|
||||||
.get(0)
|
lower_body(&mut lcx, body, decl.init_declarators[0].1, ret_ty)?;
|
||||||
.expect("single init declarator in function definition");
|
}
|
||||||
let declarator = &init_declarator.declarator;
|
}
|
||||||
|
|
||||||
let ((name_ident, _name_span), _param_decls) = declarator.decl.unwrap_with_params();
|
|
||||||
|
|
||||||
let name_sym = self.hir_symbol_intern.get_or_intern(name_ident);
|
|
||||||
|
|
||||||
if self.global_symbols.contains_key(&name_sym) {
|
|
||||||
panic!("function declarated twice! return this error properly! lol!")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct FnLoweringCtxt {
|
||||||
|
scopes: Vec<FxHashMap<Symbol, VariableInfo>>,
|
||||||
|
ir: Func,
|
||||||
|
current_bb: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FnLoweringCtxt {
|
||||||
|
fn alloca(&mut self, layout: &Layout, name: Option<Symbol>, span: Span) -> Register {
|
||||||
|
let bb = self.bb_mut();
|
||||||
|
let reg = Register(bb.regs.len().try_into().unwrap());
|
||||||
|
bb.regs.push(RegisterData { name });
|
||||||
|
let stmt = Statement {
|
||||||
|
span,
|
||||||
|
kind: StatementKind::Alloca {
|
||||||
|
reg,
|
||||||
|
size: Operand::Const(ConstValue::u64(layout.size)),
|
||||||
|
align: Operand::Const(ConstValue::u64(layout.align)),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
bb.statements.push(stmt);
|
||||||
|
reg
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bb_mut(&mut self) -> &mut BasicBlock {
|
||||||
|
&mut self.ir.bbs[self.current_bb as usize]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct VariableInfo {
|
||||||
|
def_span: Span,
|
||||||
|
ty: Ty,
|
||||||
|
ptr_to: Register,
|
||||||
|
decl_attr: DeclAttr,
|
||||||
|
layout: Layout,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lower_body(
|
||||||
|
// may be used later
|
||||||
|
_lcx: &mut LoweringCx,
|
||||||
|
body: &[(Stmt, Span)],
|
||||||
|
def_span: Span,
|
||||||
|
ret_ty: Ty,
|
||||||
|
) -> Result<Func, Error> {
|
||||||
|
let mut cx: FnLoweringCtxt = FnLoweringCtxt {
|
||||||
|
scopes: vec![FxHashMap::default()],
|
||||||
|
ir: Func {
|
||||||
|
bbs: vec![BasicBlock {
|
||||||
|
regs: Vec::new(),
|
||||||
|
statements: Vec::new(),
|
||||||
|
term: Branch::Goto(0),
|
||||||
|
}],
|
||||||
|
def_span,
|
||||||
|
ret_ty,
|
||||||
|
},
|
||||||
|
current_bb: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (stmt, stmt_span) in body {
|
||||||
|
match stmt {
|
||||||
|
Stmt::Decl(decl) => {
|
||||||
|
let decl = decl.uwnrap_normal();
|
||||||
|
let ty = lower_ty(&decl.decl_spec.ty);
|
||||||
|
let decl_attr = decl.decl_spec.attrs;
|
||||||
|
|
||||||
|
for (var, def_span) in &decl.init_declarators {
|
||||||
|
let layout = layout_of(&ty);
|
||||||
|
let (name, _) = var.declarator.decl.name();
|
||||||
|
let ptr_to = cx.alloca(&layout, Some(name), *stmt_span);
|
||||||
|
|
||||||
|
let variable_info = VariableInfo {
|
||||||
|
def_span: *def_span,
|
||||||
|
ty: ty.clone(),
|
||||||
|
ptr_to,
|
||||||
|
decl_attr,
|
||||||
|
layout,
|
||||||
|
};
|
||||||
|
cx.scopes.last_mut().unwrap().insert(name, variable_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Stmt::Labeled { .. } => todo!("labels are not implemented"),
|
||||||
|
Stmt::Compound(_) => todo!("blocks are not implemented"),
|
||||||
|
Stmt::If {
|
||||||
|
cond,
|
||||||
|
then,
|
||||||
|
otherwise,
|
||||||
|
} => todo!(),
|
||||||
|
Stmt::Switch => todo!(),
|
||||||
|
Stmt::While { cond, body } => todo!(),
|
||||||
|
Stmt::For {
|
||||||
|
init_decl,
|
||||||
|
init_expr,
|
||||||
|
cond,
|
||||||
|
post,
|
||||||
|
body,
|
||||||
|
} => todo!(),
|
||||||
|
Stmt::Goto(_) => todo!(),
|
||||||
|
Stmt::Continue => todo!(),
|
||||||
|
Stmt::Break => todo!(),
|
||||||
|
Stmt::Return(_) => todo!(),
|
||||||
|
Stmt::Expr(_) => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg!(&cx);
|
||||||
|
|
||||||
|
Ok(cx.ir)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lower_ty(ty: &TypeSpecifier) -> Ty {
|
||||||
|
match ty {
|
||||||
|
TypeSpecifier::Void => Ty::Void,
|
||||||
|
TypeSpecifier::Char => Ty::Char,
|
||||||
|
TypeSpecifier::SChar => Ty::SChar,
|
||||||
|
TypeSpecifier::UChar => Ty::UChar,
|
||||||
|
TypeSpecifier::Integer(int) => Ty::Integer(*int),
|
||||||
|
TypeSpecifier::Float => Ty::Float,
|
||||||
|
TypeSpecifier::Double => Ty::Double,
|
||||||
|
TypeSpecifier::LongDouble => Ty::LongDouble,
|
||||||
|
TypeSpecifier::Bool => Ty::Bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout_of(ty: &Ty) -> Layout {
|
||||||
|
match ty {
|
||||||
|
Ty::Void => Layout::size_align(0, 1),
|
||||||
|
Ty::Char => Layout::size_align(1, 1),
|
||||||
|
Ty::SChar => Layout::size_align(1, 1),
|
||||||
|
Ty::UChar => Layout::size_align(1, 1),
|
||||||
|
Ty::Integer(int) => match int.kind {
|
||||||
|
parser::ast::IntTyKind::Short => Layout::size_align(2, 2),
|
||||||
|
parser::ast::IntTyKind::Int => Layout::size_align(4, 4),
|
||||||
|
parser::ast::IntTyKind::Long => Layout::size_align(8, 8),
|
||||||
|
parser::ast::IntTyKind::LongLong => Layout::size_align(8, 8),
|
||||||
|
},
|
||||||
|
Ty::Float => Layout::size_align(4, 4),
|
||||||
|
Ty::Double => Layout::size_align(8, 8),
|
||||||
|
Ty::LongDouble => Layout::size_align(8, 8),
|
||||||
|
Ty::Bool => Layout::size_align(1, 1),
|
||||||
|
Ty::Struct(_) => todo!("layout_of struct"),
|
||||||
|
Ty::Union(_) => todo!("layout_of union"),
|
||||||
|
Ty::Enum(_) => todo!("layout_of enum"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
38
analysis/src/ty.rs
Normal file
38
analysis/src/ty.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
use indexmap::IndexMap;
|
||||||
|
use parser::{ast::IntTy, Symbol};
|
||||||
|
|
||||||
|
use crate::ir::DefId;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Ty {
|
||||||
|
Void,
|
||||||
|
Char,
|
||||||
|
SChar,
|
||||||
|
UChar,
|
||||||
|
Integer(IntTy),
|
||||||
|
Float,
|
||||||
|
Double,
|
||||||
|
LongDouble,
|
||||||
|
Bool,
|
||||||
|
Union(UnionTy),
|
||||||
|
Struct(StructTy),
|
||||||
|
Enum(EnumTy),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct UnionTy {
|
||||||
|
pub def_id: DefId,
|
||||||
|
pub variants: IndexMap<Symbol, Ty>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct StructTy {
|
||||||
|
pub def_id: DefId,
|
||||||
|
pub fields: IndexMap<Symbol, Ty>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct EnumTy {
|
||||||
|
pub def_id: DefId,
|
||||||
|
pub variants: IndexMap<Symbol, i128>,
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ edition = "2021"
|
||||||
bitflags = "1.3.2"
|
bitflags = "1.3.2"
|
||||||
dbg-pls = { version = "0.3.2", features = ["derive", "colors"] }
|
dbg-pls = { version = "0.3.2", features = ["derive", "colors"] }
|
||||||
peekmore = { version = "1.0.0", features = ["smallvec"] }
|
peekmore = { version = "1.0.0", features = ["smallvec"] }
|
||||||
|
lasso = "0.6.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
insta = "1.15.0"
|
insta = "1.15.0"
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ use std::fmt::Debug;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use dbg_pls::DebugPls;
|
use dbg_pls::DebugPls;
|
||||||
|
|
||||||
use crate::Spanned;
|
use crate::{sym::Symbol, Spanned};
|
||||||
|
|
||||||
pub type Ident = Spanned<String>;
|
pub type Ident = Spanned<Symbol>;
|
||||||
|
|
||||||
//
|
//
|
||||||
// --- Expr
|
// --- Expr
|
||||||
|
|
@ -114,7 +114,7 @@ pub enum Stmt {
|
||||||
},
|
},
|
||||||
Compound(Vec<Spanned<Stmt>>),
|
Compound(Vec<Spanned<Stmt>>),
|
||||||
If {
|
If {
|
||||||
cond: Expr,
|
cond: Spanned<Expr>,
|
||||||
then: Vec<Spanned<Stmt>>,
|
then: Vec<Spanned<Stmt>>,
|
||||||
otherwise: Option<Vec<Spanned<Stmt>>>,
|
otherwise: Option<Vec<Spanned<Stmt>>>,
|
||||||
},
|
},
|
||||||
|
|
@ -141,7 +141,7 @@ pub enum Stmt {
|
||||||
// --- Types and decls and garbage whatever
|
// --- Types and decls and garbage whatever
|
||||||
//
|
//
|
||||||
|
|
||||||
#[derive(Debug, DebugPls)]
|
#[derive(Debug, DebugPls, Clone, Copy)]
|
||||||
pub enum IntTySignedness {
|
pub enum IntTySignedness {
|
||||||
Signed,
|
Signed,
|
||||||
Unsigned,
|
Unsigned,
|
||||||
|
|
@ -154,7 +154,7 @@ impl Default for IntTySignedness {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, DebugPls)]
|
#[derive(Debug, DebugPls, Clone, Copy)]
|
||||||
pub enum IntTyKind {
|
pub enum IntTyKind {
|
||||||
Short,
|
Short,
|
||||||
Int,
|
Int,
|
||||||
|
|
@ -162,7 +162,7 @@ pub enum IntTyKind {
|
||||||
LongLong,
|
LongLong,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, DebugPls)]
|
#[derive(Debug, DebugPls, Clone, Copy)]
|
||||||
pub struct IntTy {
|
pub struct IntTy {
|
||||||
pub sign: IntTySignedness,
|
pub sign: IntTySignedness,
|
||||||
pub kind: IntTyKind,
|
pub kind: IntTyKind,
|
||||||
|
|
@ -283,4 +283,11 @@ impl DirectDeclarator {
|
||||||
DirectDeclarator::WithParams { ident, params } => (ident, params),
|
DirectDeclarator::WithParams { ident, params } => (ident, params),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> Ident {
|
||||||
|
match *self {
|
||||||
|
DirectDeclarator::Ident(ident) => ident,
|
||||||
|
DirectDeclarator::WithParams { ident, .. } => ident,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,20 @@
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
use ast::TranslationUnit;
|
||||||
|
|
||||||
|
use self::parser::ParserError;
|
||||||
use crate::token::Token;
|
use crate::token::Token;
|
||||||
|
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod pre;
|
mod pre;
|
||||||
mod pretty;
|
pub mod pretty;
|
||||||
|
mod sym;
|
||||||
mod token;
|
mod token;
|
||||||
|
|
||||||
|
pub use sym::Symbol;
|
||||||
|
|
||||||
pub use crate::parser::Parser;
|
pub use crate::parser::Parser;
|
||||||
|
|
||||||
pub type Spanned<T> = (T, Span);
|
pub type Spanned<T> = (T, Span);
|
||||||
|
|
@ -58,17 +64,7 @@ fn lex_and_pre(src: &str) -> impl Iterator<Item = (Token<'_>, Span)> + '_ {
|
||||||
token::pre_tokens_to_tokens(pre_tokens)
|
token::pre_tokens_to_tokens(pre_tokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_file(src: &str) {
|
pub fn parse_file(src: &str) -> Result<TranslationUnit, ParserError> {
|
||||||
let lexer = lex_and_pre(src);
|
let lexer = lex_and_pre(src);
|
||||||
let declarations = parser::parse_declarations(lexer);
|
parser::parse_declarations(lexer)
|
||||||
match declarations {
|
|
||||||
Ok(declarations) => {
|
|
||||||
dbg_pls::color!(&declarations);
|
|
||||||
let mut printer = pretty::PrettyPrinter::new(std::io::stdout().lock(), false);
|
|
||||||
println!("// START CODE -------------------");
|
|
||||||
printer.translation_unit(&declarations).unwrap();
|
|
||||||
println!("// END CODE -------------------");
|
|
||||||
}
|
|
||||||
Err(err) => eprintln!("error :(\n{:#?}", err),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ use crate::{
|
||||||
TranslationUnit, TypeSpecifier,
|
TranslationUnit, TypeSpecifier,
|
||||||
},
|
},
|
||||||
pre::Punctuator as P,
|
pre::Punctuator as P,
|
||||||
|
sym::Symbol,
|
||||||
token::{Keyword as Kw, Token as Tok},
|
token::{Keyword as Kw, Token as Tok},
|
||||||
Span, Spanned,
|
Span, Spanned,
|
||||||
};
|
};
|
||||||
|
|
@ -138,7 +139,7 @@ where
|
||||||
|
|
||||||
fn ident(&mut self) -> Result<Ident> {
|
fn ident(&mut self) -> Result<Ident> {
|
||||||
match self.next_t()? {
|
match self.next_t()? {
|
||||||
(Tok::Ident(ident), span) => Ok((ident.to_string(), span)),
|
(Tok::Ident(ident), span) => Ok((Symbol::intern(ident), span)),
|
||||||
(tok, span) => Err(ParserError::new(
|
(tok, span) => Err(ParserError::new(
|
||||||
span,
|
span,
|
||||||
format!("expected identifier, found `{tok}`"),
|
format!("expected identifier, found `{tok}`"),
|
||||||
|
|
@ -479,8 +480,14 @@ where
|
||||||
}
|
}
|
||||||
// all other stmts are indicated by keywords ...
|
// all other stmts are indicated by keywords ...
|
||||||
|
|
||||||
|
if let (Tok::Kw(Kw::If), _) = self.peek_t()? {
|
||||||
|
return self.if_statement();
|
||||||
|
}
|
||||||
|
|
||||||
// it must be an expression stmt
|
// it must be an expression stmt
|
||||||
let (expr, span) = self.expr()?;
|
let (expr, span) = self.expr()?;
|
||||||
|
expect!(self, Tok::Punct(P::Semicolon));
|
||||||
|
|
||||||
Ok((Stmt::Expr(expr), span))
|
Ok((Stmt::Expr(expr), span))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -547,6 +554,41 @@ where
|
||||||
}
|
}
|
||||||
Ok(decls)
|
Ok(decls)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compount_or_single_statement(&mut self) -> Result<Vec<Spanned<Stmt>>> {
|
||||||
|
if let Some((_, brace_span)) = eat!(self, Tok::Punct(P::BraceOpen)) {
|
||||||
|
Ok(self.compound_statement(brace_span)?.0)
|
||||||
|
} else {
|
||||||
|
let stmt = self.statement()?;
|
||||||
|
Ok(vec![stmt])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Make sure this is correct.
|
||||||
|
fn if_statement(&mut self) -> Result<Spanned<Stmt>> {
|
||||||
|
let if_span = expect!(self, Tok::Kw(Kw::If));
|
||||||
|
let _paren_span = expect!(self, Tok::Punct(P::ParenOpen));
|
||||||
|
let cond = self.expr()?;
|
||||||
|
let _paren_span = expect!(self, Tok::Punct(P::ParenClose));
|
||||||
|
let then = self.compount_or_single_statement()?;
|
||||||
|
let otherwise = if let Some(_) = eat!(self, Tok::Kw(Kw::Else)) {
|
||||||
|
Some(self.compount_or_single_statement()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let span = if_span
|
||||||
|
.extend(cond.1)
|
||||||
|
.extend_option(then.last().map(|s| s.1));
|
||||||
|
Ok((
|
||||||
|
Stmt::If {
|
||||||
|
cond,
|
||||||
|
then,
|
||||||
|
otherwise,
|
||||||
|
},
|
||||||
|
span,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'src, I> Iterator for Parser<'src, I>
|
impl<'src, I> Iterator for Parser<'src, I>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
parser::{eat, expect, Parser, ParserError, Result},
|
parser::{eat, expect, Parser, ParserError, Result},
|
||||||
pre::Punctuator as P,
|
pre::Punctuator as P,
|
||||||
|
sym::Symbol,
|
||||||
token::{Constant, Token as Tok},
|
token::{Constant, Token as Tok},
|
||||||
Span, Spanned,
|
Span, Spanned,
|
||||||
};
|
};
|
||||||
|
|
@ -23,7 +24,7 @@ where
|
||||||
|
|
||||||
fn get_lhs(&mut self) -> Result<Spanned<Expr>> {
|
fn get_lhs(&mut self) -> Result<Spanned<Expr>> {
|
||||||
let (typ, span) = match self.peek_t()? {
|
let (typ, span) = match self.peek_t()? {
|
||||||
&(Tok::Ident(ident), span) => (Atom::Ident((ident.to_string(), span)), span),
|
&(Tok::Ident(ident), span) => (Atom::Ident((Symbol::intern(ident), span)), span),
|
||||||
&(Tok::StringLiteral(literal), span) => (Atom::String(literal.to_string()), span),
|
&(Tok::StringLiteral(literal), span) => (Atom::String(literal.to_string()), span),
|
||||||
&(Tok::Constant(Constant::Int(int)), span) => (Atom::Int(int), span),
|
&(Tok::Constant(Constant::Int(int)), span) => (Atom::Int(int), span),
|
||||||
&(Tok::Constant(Constant::Float(float)), span) => (Atom::Float(float), span),
|
&(Tok::Constant(Constant::Float(float)), span) => (Atom::Float(float), span),
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: WithParams {
|
decl: WithParams {
|
||||||
ident: ("main", 5..9),
|
ident: (main, 5..9),
|
||||||
params: [],
|
params: [],
|
||||||
},
|
},
|
||||||
pointer: false,
|
pointer: false,
|
||||||
|
|
@ -39,7 +39,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("i", 22..23)),
|
decl: Ident((i, 22..23)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(0)), 26..27)),
|
init: Some((Atom(Int(0)), 26..27)),
|
||||||
|
|
@ -62,7 +62,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("f", 39..40)),
|
decl: Ident((f, 39..40)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((
|
init: Some((
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
---
|
||||||
|
source: parser/src/parser/tests.rs
|
||||||
|
expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
|
---
|
||||||
|
(
|
||||||
|
Ok([
|
||||||
|
(
|
||||||
|
FunctionDef(FunctionDef {
|
||||||
|
decl: Normal(NormalDecl {
|
||||||
|
decl_spec: DeclSpec {
|
||||||
|
ty: Integer(IntTy { sign: Signed, kind: Int }),
|
||||||
|
attrs: "(empty)",
|
||||||
|
},
|
||||||
|
init_declarators: [
|
||||||
|
(
|
||||||
|
InitDecl {
|
||||||
|
declarator: Declarator {
|
||||||
|
decl: WithParams {
|
||||||
|
ident: (main, 5..9),
|
||||||
|
params: [],
|
||||||
|
},
|
||||||
|
pointer: false,
|
||||||
|
},
|
||||||
|
init: None,
|
||||||
|
},
|
||||||
|
5..9,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
body: [
|
||||||
|
(
|
||||||
|
If {
|
||||||
|
cond: (Atom(Int(1)), 22..23),
|
||||||
|
then: [(Expr(Atom(String("a"))), 35..37)],
|
||||||
|
otherwise: Some([
|
||||||
|
(
|
||||||
|
If {
|
||||||
|
cond: (Atom(Int(2)), 55..56),
|
||||||
|
then: [(Expr(Atom(String("b"))), 68..70)],
|
||||||
|
otherwise: Some([(Expr(Atom(String("c"))), 94..96)]),
|
||||||
|
},
|
||||||
|
51..70,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
18..37,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
1..106,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
"int main() {\n if (1) {\n \"a\"\n } else {\n if (2) {\n \"b\"\n } else {\n \"c\"\n }\n }\n}\n",
|
||||||
|
)
|
||||||
|
|
@ -16,7 +16,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: WithParams {
|
decl: WithParams {
|
||||||
ident: ("uwu", 5..8),
|
ident: (uwu, 5..8),
|
||||||
params: [
|
params: [
|
||||||
FunctionParamDecl {
|
FunctionParamDecl {
|
||||||
decl_spec: (
|
decl_spec: (
|
||||||
|
|
@ -28,7 +28,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
),
|
),
|
||||||
declarator: (
|
declarator: (
|
||||||
Declarator {
|
Declarator {
|
||||||
decl: Ident(("owo", 14..17)),
|
decl: Ident((owo, 14..17)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
14..17,
|
14..17,
|
||||||
|
|
@ -44,7 +44,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
),
|
),
|
||||||
declarator: (
|
declarator: (
|
||||||
Declarator {
|
Declarator {
|
||||||
decl: Ident(("qwq", 23..26)),
|
decl: Ident((qwq, 23..26)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
23..26,
|
23..26,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: WithParams {
|
decl: WithParams {
|
||||||
ident: ("uwu", 35..38),
|
ident: (uwu, 35..38),
|
||||||
params: [],
|
params: [],
|
||||||
},
|
},
|
||||||
pointer: false,
|
pointer: false,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: WithParams {
|
decl: WithParams {
|
||||||
ident: ("uwu", 6..9),
|
ident: (uwu, 6..9),
|
||||||
params: [],
|
params: [],
|
||||||
},
|
},
|
||||||
pointer: false,
|
pointer: false,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: WithParams {
|
decl: WithParams {
|
||||||
ident: ("main", 5..9),
|
ident: (main, 5..9),
|
||||||
params: [],
|
params: [],
|
||||||
},
|
},
|
||||||
pointer: false,
|
pointer: false,
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("test", 5..9)),
|
decl: Ident((test, 5..9)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: None,
|
init: None,
|
||||||
|
|
@ -38,7 +38,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("uwu", 32..35)),
|
decl: Ident((uwu, 32..35)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: None,
|
init: None,
|
||||||
|
|
@ -48,7 +48,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("owo", 37..40)),
|
decl: Ident((owo, 37..40)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: None,
|
init: None,
|
||||||
|
|
@ -72,7 +72,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: WithParams {
|
decl: WithParams {
|
||||||
ident: ("function", 68..76),
|
ident: (function, 68..76),
|
||||||
params: [],
|
params: [],
|
||||||
},
|
},
|
||||||
pointer: false,
|
pointer: false,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: WithParams {
|
decl: WithParams {
|
||||||
ident: ("main", 5..9),
|
ident: (main, 5..9),
|
||||||
params: [],
|
params: [],
|
||||||
},
|
},
|
||||||
pointer: false,
|
pointer: false,
|
||||||
|
|
@ -31,7 +31,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
Expr(
|
Expr(
|
||||||
Postfix(ExprPostfix {
|
Postfix(ExprPostfix {
|
||||||
lhs: (Atom(Ident(("puts", 18..22))), 18..22),
|
lhs: (Atom(Ident((puts, 18..22))), 18..22),
|
||||||
op: Call([(Atom(String("Hello, world!")), 23..37)]),
|
op: Call([(Atom(String("Hello, world!")), 23..37)]),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
---
|
||||||
|
source: parser/src/parser/tests.rs
|
||||||
|
expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
|
---
|
||||||
|
(
|
||||||
|
Ok([
|
||||||
|
(
|
||||||
|
FunctionDef(FunctionDef {
|
||||||
|
decl: Normal(NormalDecl {
|
||||||
|
decl_spec: DeclSpec {
|
||||||
|
ty: Integer(IntTy { sign: Signed, kind: Int }),
|
||||||
|
attrs: "(empty)",
|
||||||
|
},
|
||||||
|
init_declarators: [
|
||||||
|
(
|
||||||
|
InitDecl {
|
||||||
|
declarator: Declarator {
|
||||||
|
decl: WithParams {
|
||||||
|
ident: (main, 5..9),
|
||||||
|
params: [],
|
||||||
|
},
|
||||||
|
pointer: false,
|
||||||
|
},
|
||||||
|
init: None,
|
||||||
|
},
|
||||||
|
5..9,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
body: [
|
||||||
|
(
|
||||||
|
If {
|
||||||
|
cond: (Atom(Int(1)), 22..23),
|
||||||
|
then: [(Expr(Atom(String("a"))), 35..37)],
|
||||||
|
otherwise: Some([(Expr(Atom(String("b"))), 61..63)]),
|
||||||
|
},
|
||||||
|
18..37,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
1..73,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
"int main() {\n if (1) {\n \"a\"\n } else {\n \"b\"\n }\n}\n",
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
---
|
||||||
|
source: parser/src/parser/tests.rs
|
||||||
|
expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
|
---
|
||||||
|
(
|
||||||
|
Ok([
|
||||||
|
(
|
||||||
|
FunctionDef(FunctionDef {
|
||||||
|
decl: Normal(NormalDecl {
|
||||||
|
decl_spec: DeclSpec {
|
||||||
|
ty: Integer(IntTy { sign: Signed, kind: Int }),
|
||||||
|
attrs: "(empty)",
|
||||||
|
},
|
||||||
|
init_declarators: [
|
||||||
|
(
|
||||||
|
InitDecl {
|
||||||
|
declarator: Declarator {
|
||||||
|
decl: WithParams {
|
||||||
|
ident: (main, 5..9),
|
||||||
|
params: [],
|
||||||
|
},
|
||||||
|
pointer: false,
|
||||||
|
},
|
||||||
|
init: None,
|
||||||
|
},
|
||||||
|
5..9,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
body: [
|
||||||
|
(
|
||||||
|
If {
|
||||||
|
cond: (Atom(Int(1)), 22..23),
|
||||||
|
then: [(Expr(Atom(String("a"))), 33..35)],
|
||||||
|
otherwise: Some([(Expr(Atom(String("b"))), 55..57)]),
|
||||||
|
},
|
||||||
|
18..35,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
1..61,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
"int main() {\n if (1) {\n \"a\"\n } else {\n \"b\"\n }\n}\n",
|
||||||
|
)
|
||||||
|
|
@ -15,7 +15,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("a", 24..25)),
|
decl: Ident((a, 24..25)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(1)), 28..29)),
|
init: Some((Atom(Int(1)), 28..29)),
|
||||||
|
|
@ -38,7 +38,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("b", 54..55)),
|
decl: Ident((b, 54..55)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(2)), 58..59)),
|
init: Some((Atom(Int(2)), 58..59)),
|
||||||
|
|
@ -61,7 +61,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("c", 84..85)),
|
decl: Ident((c, 84..85)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(3)), 88..89)),
|
init: Some((Atom(Int(3)), 88..89)),
|
||||||
|
|
@ -84,7 +84,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("d", 115..116)),
|
decl: Ident((d, 115..116)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(4)), 119..120)),
|
init: Some((Atom(Int(4)), 119..120)),
|
||||||
|
|
@ -107,7 +107,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("e", 145..146)),
|
decl: Ident((e, 145..146)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(6)), 149..150)),
|
init: Some((Atom(Int(6)), 149..150)),
|
||||||
|
|
@ -130,7 +130,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("f", 175..176)),
|
decl: Ident((f, 175..176)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(5)), 179..180)),
|
init: Some((Atom(Int(5)), 179..180)),
|
||||||
|
|
@ -153,7 +153,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("g", 205..206)),
|
decl: Ident((g, 205..206)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(7)), 209..210)),
|
init: Some((Atom(Int(7)), 209..210)),
|
||||||
|
|
@ -179,7 +179,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("h", 235..236)),
|
decl: Ident((h, 235..236)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(8)), 239..240)),
|
init: Some((Atom(Int(8)), 239..240)),
|
||||||
|
|
@ -205,7 +205,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("i", 265..266)),
|
decl: Ident((i, 265..266)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(9)), 269..270)),
|
init: Some((Atom(Int(9)), 269..270)),
|
||||||
|
|
@ -228,7 +228,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("j", 296..297)),
|
decl: Ident((j, 296..297)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(10)), 300..302)),
|
init: Some((Atom(Int(10)), 300..302)),
|
||||||
|
|
@ -251,7 +251,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("k", 327..328)),
|
decl: Ident((k, 327..328)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(11)), 331..333)),
|
init: Some((Atom(Int(11)), 331..333)),
|
||||||
|
|
@ -274,7 +274,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("l", 358..359)),
|
decl: Ident((l, 358..359)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(12)), 362..364)),
|
init: Some((Atom(Int(12)), 362..364)),
|
||||||
|
|
@ -297,7 +297,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("m", 389..390)),
|
decl: Ident((m, 389..390)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(13)), 393..395)),
|
init: Some((Atom(Int(13)), 393..395)),
|
||||||
|
|
@ -320,7 +320,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("n", 420..421)),
|
decl: Ident((n, 420..421)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(14)), 424..426)),
|
init: Some((Atom(Int(14)), 424..426)),
|
||||||
|
|
@ -343,7 +343,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("o", 452..453)),
|
decl: Ident((o, 452..453)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(15)), 456..458)),
|
init: Some((Atom(Int(15)), 456..458)),
|
||||||
|
|
@ -366,7 +366,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("p", 483..484)),
|
decl: Ident((p, 483..484)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(16)), 487..489)),
|
init: Some((Atom(Int(16)), 487..489)),
|
||||||
|
|
@ -389,7 +389,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("q", 514..515)),
|
decl: Ident((q, 514..515)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(17)), 518..520)),
|
init: Some((Atom(Int(17)), 518..520)),
|
||||||
|
|
@ -412,7 +412,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("r", 545..546)),
|
decl: Ident((r, 545..546)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(18)), 549..551)),
|
init: Some((Atom(Int(18)), 549..551)),
|
||||||
|
|
@ -438,7 +438,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("s", 576..577)),
|
decl: Ident((s, 576..577)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(19)), 580..582)),
|
init: Some((Atom(Int(19)), 580..582)),
|
||||||
|
|
@ -464,7 +464,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("t", 607..608)),
|
decl: Ident((t, 607..608)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(20)), 611..613)),
|
init: Some((Atom(Int(20)), 611..613)),
|
||||||
|
|
@ -490,7 +490,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("u", 639..640)),
|
decl: Ident((u, 639..640)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(21)), 643..645)),
|
init: Some((Atom(Int(21)), 643..645)),
|
||||||
|
|
@ -516,7 +516,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("v", 670..671)),
|
decl: Ident((v, 670..671)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(22)), 674..676)),
|
init: Some((Atom(Int(22)), 674..676)),
|
||||||
|
|
@ -542,7 +542,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("w", 701..702)),
|
decl: Ident((w, 701..702)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(23)), 705..707)),
|
init: Some((Atom(Int(23)), 705..707)),
|
||||||
|
|
@ -568,7 +568,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("x", 732..733)),
|
decl: Ident((x, 732..733)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(24)), 736..738)),
|
init: Some((Atom(Int(24)), 736..738)),
|
||||||
|
|
@ -594,7 +594,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("y", 763..764)),
|
decl: Ident((y, 763..764)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(25)), 767..769)),
|
init: Some((Atom(Int(25)), 767..769)),
|
||||||
|
|
@ -620,7 +620,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("z", 794..795)),
|
decl: Ident((z, 794..795)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((Atom(Int(26)), 798..800)),
|
init: Some((Atom(Int(26)), 798..800)),
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("x", 5..6)),
|
decl: Ident((x, 5..6)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((
|
init: Some((
|
||||||
|
|
@ -45,7 +45,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("y", 21..22)),
|
decl: Ident((y, 21..22)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((
|
init: Some((
|
||||||
|
|
@ -82,12 +82,12 @@ expression: "(parsed_pretty, pretty_printed_source)"
|
||||||
(
|
(
|
||||||
InitDecl {
|
InitDecl {
|
||||||
declarator: Declarator {
|
declarator: Declarator {
|
||||||
decl: Ident(("z", 45..46)),
|
decl: Ident((z, 45..46)),
|
||||||
pointer: false,
|
pointer: false,
|
||||||
},
|
},
|
||||||
init: Some((
|
init: Some((
|
||||||
Binary(ExprBinary {
|
Binary(ExprBinary {
|
||||||
lhs: (Atom(Ident(("array", 50..55))), 50..55),
|
lhs: (Atom(Ident((array, 50..55))), 50..55),
|
||||||
rhs: (Atom(Int(9)), 56..57),
|
rhs: (Atom(Int(9)), 56..57),
|
||||||
op: Index,
|
op: Index,
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -156,3 +156,49 @@ int main() {
|
||||||
"#
|
"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn if_else() {
|
||||||
|
parse_test!(
|
||||||
|
r#"
|
||||||
|
int main() {
|
||||||
|
if (1) {
|
||||||
|
"a";
|
||||||
|
} else {
|
||||||
|
"b";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn if_else_braceless() {
|
||||||
|
parse_test!(
|
||||||
|
r#"
|
||||||
|
int main() {
|
||||||
|
if (1)
|
||||||
|
"a";
|
||||||
|
else
|
||||||
|
"b";
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn else_if() {
|
||||||
|
parse_test!(
|
||||||
|
r#"
|
||||||
|
int main() {
|
||||||
|
if (1) {
|
||||||
|
"a";
|
||||||
|
} else if (2) {
|
||||||
|
"b";
|
||||||
|
} else {
|
||||||
|
"c";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
FunctionParamDecl, InitDecl, IntTyKind, IntTySignedness, NormalDecl, PostfixOp, Stmt,
|
FunctionParamDecl, InitDecl, IntTyKind, IntTySignedness, NormalDecl, PostfixOp, Stmt,
|
||||||
TypeSpecifier, UnaryOp,
|
TypeSpecifier, UnaryOp,
|
||||||
},
|
},
|
||||||
|
sym::Symbol,
|
||||||
Span, Spanned,
|
Span, Spanned,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -33,6 +34,10 @@ impl<W: Write> PrettyPrinter<W> {
|
||||||
write!(self.output, "{}", str)
|
write!(self.output, "{}", str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sym(&mut self, sym: Symbol) -> Result {
|
||||||
|
sym.as_str(|sym| self.string(sym))
|
||||||
|
}
|
||||||
|
|
||||||
fn print_indent(&mut self) -> Result {
|
fn print_indent(&mut self) -> Result {
|
||||||
self.string(&INDENT.repeat(self.indent))
|
self.string(&INDENT.repeat(self.indent))
|
||||||
}
|
}
|
||||||
|
|
@ -88,6 +93,7 @@ impl<W: Write> PrettyPrinter<W> {
|
||||||
self.linebreak()?;
|
self.linebreak()?;
|
||||||
}
|
}
|
||||||
self.dedent();
|
self.dedent();
|
||||||
|
self.print_indent()?;
|
||||||
self.string("}")?;
|
self.string("}")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +102,7 @@ impl<W: Write> PrettyPrinter<W> {
|
||||||
match stmt {
|
match stmt {
|
||||||
Stmt::Decl(decl) => self.decl(decl, false),
|
Stmt::Decl(decl) => self.decl(decl, false),
|
||||||
Stmt::Labeled { label, stmt } => {
|
Stmt::Labeled { label, stmt } => {
|
||||||
self.string(&label.0)?;
|
self.sym(label.0)?;
|
||||||
self.string(":")?;
|
self.string(":")?;
|
||||||
self.linebreak()?;
|
self.linebreak()?;
|
||||||
self.print_indent()?;
|
self.print_indent()?;
|
||||||
|
|
@ -105,7 +111,7 @@ impl<W: Write> PrettyPrinter<W> {
|
||||||
}
|
}
|
||||||
Stmt::Compound(body) => self.block(body),
|
Stmt::Compound(body) => self.block(body),
|
||||||
Stmt::If {
|
Stmt::If {
|
||||||
cond,
|
cond: (cond, _),
|
||||||
then,
|
then,
|
||||||
otherwise,
|
otherwise,
|
||||||
} => {
|
} => {
|
||||||
|
|
@ -163,7 +169,7 @@ impl<W: Write> PrettyPrinter<W> {
|
||||||
}
|
}
|
||||||
Stmt::Goto((label, _)) => {
|
Stmt::Goto((label, _)) => {
|
||||||
self.string("goto ")?;
|
self.string("goto ")?;
|
||||||
self.string(label)?;
|
self.sym(*label)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Stmt::Continue => self.string("continue"),
|
Stmt::Continue => self.string("continue"),
|
||||||
|
|
@ -276,9 +282,9 @@ impl<W: Write> PrettyPrinter<W> {
|
||||||
|
|
||||||
fn direct_declarator(&mut self, declarator: &DirectDeclarator) -> Result {
|
fn direct_declarator(&mut self, declarator: &DirectDeclarator) -> Result {
|
||||||
match declarator {
|
match declarator {
|
||||||
DirectDeclarator::Ident(ident) => self.string(&ident.0),
|
DirectDeclarator::Ident(ident) => self.sym(ident.0),
|
||||||
DirectDeclarator::WithParams { ident, params } => {
|
DirectDeclarator::WithParams { ident, params } => {
|
||||||
self.string(&ident.0)?;
|
self.sym(ident.0)?;
|
||||||
self.string("(")?;
|
self.string("(")?;
|
||||||
self.function_param_decls(params)?;
|
self.function_param_decls(params)?;
|
||||||
self.string(")")?;
|
self.string(")")?;
|
||||||
|
|
@ -304,7 +310,7 @@ impl<W: Write> PrettyPrinter<W> {
|
||||||
fn expr(&mut self, expr: &Expr) -> Result {
|
fn expr(&mut self, expr: &Expr) -> Result {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Atom(atom) => match atom {
|
Expr::Atom(atom) => match atom {
|
||||||
Atom::Ident((ident, _)) => self.string(ident),
|
Atom::Ident((ident, _)) => self.sym(*ident),
|
||||||
Atom::Int(int) => write!(self.output, "{}", int),
|
Atom::Int(int) => write!(self.output, "{}", int),
|
||||||
Atom::Float(float) => write!(self.output, "{}", float),
|
Atom::Float(float) => write!(self.output, "{}", float),
|
||||||
Atom::String(string) => {
|
Atom::String(string) => {
|
||||||
|
|
@ -353,12 +359,12 @@ impl<W: Write> PrettyPrinter<W> {
|
||||||
}
|
}
|
||||||
PostfixOp::Member((ident, _)) => {
|
PostfixOp::Member((ident, _)) => {
|
||||||
self.string(".")?;
|
self.string(".")?;
|
||||||
self.string(ident)?;
|
self.sym(*ident)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
PostfixOp::ArrowMember((ident, _)) => {
|
PostfixOp::ArrowMember((ident, _)) => {
|
||||||
self.string("->")?;
|
self.string("->")?;
|
||||||
self.string(ident)?;
|
self.sym(*ident)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
PostfixOp::Increment => self.string("++"),
|
PostfixOp::Increment => self.string("++"),
|
||||||
|
|
|
||||||
39
parser/src/sym.rs
Normal file
39
parser/src/sym.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
use std::{cell::RefCell, fmt::Debug, marker::PhantomData};
|
||||||
|
|
||||||
|
use dbg_pls::DebugPls;
|
||||||
|
use lasso::Spur;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Symbol {
|
||||||
|
spur: Spur,
|
||||||
|
not_send: PhantomData<*const ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_local! {
|
||||||
|
static INTERNER: RefCell<lasso::Rodeo> = RefCell::new(lasso::Rodeo::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Symbol {
|
||||||
|
pub fn intern(s: &str) -> Self {
|
||||||
|
INTERNER.with(|i| Symbol {
|
||||||
|
spur: i.borrow_mut().get_or_intern(s),
|
||||||
|
not_send: PhantomData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_str<R>(&self, f: impl FnOnce(&str) -> R) -> R {
|
||||||
|
INTERNER.with(|i| f(i.borrow_mut().resolve(&self.spur)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for Symbol {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
INTERNER.with(|i| f.write_str(i.borrow_mut().resolve(&self.spur)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebugPls for Symbol {
|
||||||
|
fn fmt(&self, f: dbg_pls::Formatter<'_>) {
|
||||||
|
self.as_str(|s| f.debug_ident(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/main.rs
21
src/main.rs
|
|
@ -1,10 +1,19 @@
|
||||||
use std::error::Error;
|
fn main() {
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
|
||||||
let input_file = std::env::args().nth(1).expect("first argument");
|
let input_file = std::env::args().nth(1).expect("first argument");
|
||||||
let src = std::fs::read_to_string(input_file)?;
|
let src = std::fs::read_to_string(&input_file).unwrap_or_else(|err| {
|
||||||
|
eprintln!("failed to read file {input_file}: {err}");
|
||||||
|
std::process::exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
parser::parse_file(&src);
|
let ast = parser::parse_file(&src);
|
||||||
|
dbg_pls::color!(&ast);
|
||||||
|
let Ok(ast) = ast else {
|
||||||
|
std::process::exit(1);
|
||||||
|
};
|
||||||
|
let mut printer = parser::pretty::PrettyPrinter::new(std::io::stdout().lock(), false);
|
||||||
|
println!("// START CODE -------------------");
|
||||||
|
printer.translation_unit(&ast).unwrap();
|
||||||
|
println!("// END CODE -------------------");
|
||||||
|
|
||||||
Ok(())
|
let _ = analysis::lower_translation_unit(&ast);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue