Skip to content

Commit

Permalink
(closes #44 - feature/translate-if/44)
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit aa5362b
Author: Brandon Li <[email protected]>
Date:   Tue Mar 14 21:59:54 2023 -0700

    fmt

commit 70948f2
Author: Brandon Li <[email protected]>
Date:   Tue Mar 14 21:59:40 2023 -0700

    lint fmt

commit 9ce6908
Author: Brandon Li <[email protected]>
Date:   Mon Mar 13 15:03:20 2023 -0700

    cleanup tests for compilation error

commit 6ad5480
Author: Brandon Li <[email protected]>
Date:   Fri Mar 10 15:42:01 2023 -0800

    shadow as declared

commit ec99266
Author: Brandon Li <[email protected]>
Date:   Fri Mar 10 14:18:46 2023 -0800

    type reference parsed

commit 9f99768
Author: Brandon Li <[email protected]>
Date:   Wed Mar 8 19:42:29 2023 -0800

    reg alloc if

commit a541dec
Author: Brandon Li <[email protected]>
Date:   Tue Mar 7 21:28:52 2023 -0800

    translate if
  • Loading branch information
brandonLi8 committed Mar 15, 2023
1 parent d1f34d6 commit 23cbfae
Show file tree
Hide file tree
Showing 42 changed files with 1,696 additions and 356 deletions.
1 change: 1 addition & 0 deletions .clippy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@
-A clippy::needless_pass_by_value
-A clippy::new-without-default
-A clippy::range-plus-one
-A clippy::too-many-lines
-A clippy::trivial_regex
58 changes: 48 additions & 10 deletions examples/example.sol
Original file line number Diff line number Diff line change
@@ -1,16 +1,54 @@
if a < b {
1 + 2;
2 + 3
let a: int = let b: int = a

##
let a: int = 0
let b: int = 0
let c: int = 0

let d: int = if (if true { c <= 0 } else { 1 + 2 + 3 < 6 }) {
a + b
}
else if c {
2 + 3
else if (if false { false } else { true }) {
2
}
else if d {
1 + 2
else {
let d: int = b + c + 2
}



let a = 0
let b = 0
let c = 0

let temp2 = if true { {a, b, c}
c <= 0 {temp2, a, b, c}
}
else {
let temp0 = 1 + 2 {temp2, a, b, c}
let temp1 = temp0 + temp3 {temp0, temp2, a, b, c}
temp1 < 6 {temp1, temp2, a, b, c}
}
else if c {
a

let d = if temp2 { {temp2, a, b, c}
a + b {d, a, b}
}
else {
2 + 1
let temp3 = if false { {d, b, c}
false
}
else {
true
}

if temp3 { {d, b, c, temp3}
2 {d}
} else {
let temp4 = b + c {d, b, c}
let e = temp4 + 2 {d, temp4}
e {e, d}
}
}

d {d}
##
7 changes: 3 additions & 4 deletions src/compiler/compile_binary_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ use asm::asm::{FloatRegister::*, Instruction, Instruction::*, Operand::*, Regist
use compiler::compiler::compile_direct;
use compiler::symbol_table::{Location, SymbolTable};
use error_messages::internal_compiler_error;
use ir::ir::{BinaryExprKind, DirectExpr};
use ir::type_checker::SolisType;
use ir::ir::{BinaryExprKind, DirectExpr, Type};

/// Compiles a binary expression into assembly instructions, pushing the results into `instructions`
/// * `kind` - the type of binary expression
Expand All @@ -28,12 +27,12 @@ pub fn compile_binary_expr(
kind: &BinaryExprKind,
operand_1: &DirectExpr,
operand_2: &DirectExpr,
operand_type: &SolisType,
operand_type: &Type,
location: &Location,
symbol_table: &mut SymbolTable,
instructions: &mut Vec<Instruction>,
) {
if let SolisType::Float = operand_type {
if let Type::Float = operand_type {
return compile_binary_expr_float(kind, operand_1, operand_2, location, symbol_table, instructions);
}

Expand Down
11 changes: 5 additions & 6 deletions src/compiler/compile_unary_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ use asm::asm::{FloatRegister::*, Instruction, Instruction::*, Operand::*, Regist
use compiler::compiler::{compile_direct, mov_instruction_safe};
use compiler::symbol_table::{Location, SymbolTable};
use error_messages::internal_compiler_error;
use ir::ir::{DirectExpr, UnaryExprKind};
use ir::type_checker::SolisType;
use ir::ir::{DirectExpr, Type, UnaryExprKind};

/// Compiles a unary expression into assembly instructions, pushing the results into `instructions`
/// * kind - the type of unary expression
Expand All @@ -26,7 +25,7 @@ use ir::type_checker::SolisType;
pub fn compile_unary_expr(
kind: &UnaryExprKind,
operand: &DirectExpr,
operand_type: &SolisType,
operand_type: &Type,
location: &Location,
symbol_table: &mut SymbolTable,
instructions: &mut Vec<Instruction>,
Expand All @@ -37,7 +36,7 @@ pub fn compile_unary_expr(
instructions.push(Comment(format!("{kind:?}, {operand:?}"))); // TODO: option?

match (kind, operand_type) {
(UnaryExprKind::Not, SolisType::Bool) => {
(UnaryExprKind::Not, Type::Bool) => {
// The first operand of the `Cmp` instruction must be a Reg/MemOffset
if matches!(asm_operand, Imm(..)) {
instructions.push(Mov(Reg(R14), asm_operand));
Expand All @@ -51,12 +50,12 @@ pub fn compile_unary_expr(

instructions.push(Setz(location.to_operand()));
}
(UnaryExprKind::Negative, SolisType::Int) => {
(UnaryExprKind::Negative, Type::Int) => {
// No temporary registers are needed since, asm_operand is used, and then location is modified.
mov_instruction_safe(location.to_operand(), asm_operand, instructions, R14);
instructions.push(Neg(location.to_operand()));
}
(UnaryExprKind::Negative, SolisType::Float) => {
(UnaryExprKind::Negative, Type::Float) => {
// Floating Point negation
instructions.push(Xorpd(FloatReg(Xmm14), FloatReg(Xmm14)));
instructions.push(Subsd(FloatReg(Xmm14), asm_operand));
Expand Down
12 changes: 7 additions & 5 deletions src/compiler/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ use compiler::compile_binary_expr::compile_binary_expr;
use compiler::compile_unary_expr::compile_unary_expr;
use compiler::symbol_table::{Location, SymbolTable};
use error_messages::internal_compiler_error;
use ir::ir::{Block, DirectExpr, Expr, Program};
use ir::type_checker::SolisType;
use ir::ir::{Block, DirectExpr, Expr, Program, Type};
use register_allocation::register_allocator::allocate_registers;
use register_allocation::register_allocator::{Assignment, Map, Set};

Expand Down Expand Up @@ -53,6 +52,8 @@ fn compile_block(
]),
);

// println!("{:#?}", block);
// println!("{:#?}", variable_assignment);
// Compile each expression
for (i, expr) in block.exprs.iter().enumerate() {
compile_expr(
Expand Down Expand Up @@ -171,6 +172,7 @@ pub fn compile_expr(
|| internal_compiler_error("coercion must have location"),
|location| compile_type_coercion(expr, location, from_type, to_type, symbol_table, instructions),
),
Expr::If { .. } => todo!(),
}
}

Expand All @@ -180,15 +182,15 @@ pub fn compile_expr(
pub fn compile_type_coercion(
expr: &DirectExpr,
location: &Location,
from_type: &SolisType,
to_type: &SolisType,
from_type: &Type,
to_type: &Type,
symbol_table: &mut SymbolTable,
instructions: &mut Vec<Instruction>,
) {
let mut asm_operand = compile_direct(expr, symbol_table);

match (from_type, to_type) {
(SolisType::Int, SolisType::Float) => {
(Type::Int, Type::Float) => {
// The second operand of Cvtsi2sd must not be a immediate
if let Imm(..) = asm_operand {
instructions.push(Mov(Reg(R14), asm_operand));
Expand Down
20 changes: 14 additions & 6 deletions src/error_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! compiler fails to compile a piece of computer program source code.
use colored::Colorize;
use ir::type_checker::SolisType;
use ir::ir::Type;
use std::backtrace::Backtrace;
use std::fmt::{self, Display};
use std::ops::Range;
Expand Down Expand Up @@ -43,7 +43,14 @@ pub fn compilation_error(file: &File, position: &Range<usize>, message: &str) ->
let line_number = newline_indicies.len();
let column = position.start - prev_newline;

println!(
// Disable coloring on unit tests.
#[cfg(feature = "test")]
{
use colored::control::SHOULD_COLORIZE;
SHOULD_COLORIZE.set_override(false);
}

let error_message = format!(
"{error}: {message}\n {arrow} {filename}:{line_number}:{column}\n \
{bar_padding}{bar}\n\
{display_line_number} {bar} {line}\n \
Expand All @@ -65,8 +72,9 @@ pub fn compilation_error(file: &File, position: &Range<usize>, message: &str) ->
// For testing purposes, we don't want to exit() when we want to test that certain inputs raise errors.
// Instead, we are able to test for panics.
if cfg!(feature = "test") {
panic!("{} at {:?}", message, position);
panic!("{}", error_message.normal());
} else {
println!("{error_message}");
std::process::exit(exitcode::DATAERR)
}
}
Expand All @@ -89,14 +97,14 @@ pub fn internal_compiler_error(message: &str) -> ! {
}
}

/// For user facing, create more precise display messages for `SolisTypes` for error messaging purposes.
impl Display for SolisType {
/// For user facing, create more precise display messages for `Types` for error messaging purposes.
impl Display for Type {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Unit => write!(f, "<unit>"),
Self::Int => write!(f, "int"),
Self::Bool => write!(f, "bool"),
Self::Float => write!(f, "float"),
Self::Custom(s) => write!(f, "{s}"),
}
}
}
25 changes: 18 additions & 7 deletions src/ir/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@
//! Working with directs means that the operator does not have to do any more computation (naively would have to store
//! results on the stack).
use ir::type_checker::SolisType;

#[derive(PartialEq, Debug)]
pub struct Program {
pub body: Block,
Expand All @@ -64,23 +62,28 @@ pub enum Expr {
id: String,
init_expr: Box<Expr>,
},
If {
condition: Box<DirectExpr>,
then_block: Block,
else_block: Option<Block>,
},
UnaryExpr {
kind: UnaryExprKind,
operand: Box<DirectExpr>,
operand_type: SolisType,
operand_type: Type,
},
BinaryExpr {
kind: BinaryExprKind,
operand_1: Box<DirectExpr>,
operand_2: Box<DirectExpr>,
operand_type: SolisType,
operand_type: Type,
},

// Converts one type to another type. We do this in the IR layer instead of the compiler layer
TypeCoercion {
expr: Box<DirectExpr>,
from_type: SolisType,
to_type: SolisType,
from_type: Type,
to_type: Type,
},
}

Expand All @@ -89,7 +92,15 @@ pub enum DirectExpr {
Int { value: i64 },
Bool { value: bool },
Float { value: f64 },
Id { value: String, id_type: SolisType },
Id { value: String, id_type: Type },
}

#[derive(PartialEq, Clone, Debug)]
pub enum Type {
Unit,
Int,
Bool,
Float,
}

#[derive(PartialEq, Debug)]
Expand Down
Loading

0 comments on commit 23cbfae

Please sign in to comment.