.
This commit is contained in:
@@ -24,7 +24,7 @@ impl Span {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum BinOp {
|
pub enum BinOp {
|
||||||
Add,
|
Add,
|
||||||
Sub,
|
Sub,
|
||||||
@@ -45,11 +45,20 @@ impl BinOp {
|
|||||||
|
|
||||||
impl fmt::Display for BinOp {
|
impl fmt::Display for BinOp {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
if f.alternate() {
|
||||||
BinOp::Add => f.write_str("+"),
|
match self {
|
||||||
BinOp::Sub => f.write_str("-"),
|
BinOp::Add => f.write_str("add"),
|
||||||
BinOp::Mul => f.write_str("*"),
|
BinOp::Sub => f.write_str("sub"),
|
||||||
BinOp::Div => f.write_str("/"),
|
BinOp::Mul => f.write_str("mul"),
|
||||||
|
BinOp::Div => f.write_str("div"),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match self {
|
||||||
|
BinOp::Add => f.write_str("+"),
|
||||||
|
BinOp::Sub => f.write_str("-"),
|
||||||
|
BinOp::Mul => f.write_str("*"),
|
||||||
|
BinOp::Div => f.write_str("/"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,13 +83,13 @@ fn convert_to_typed_expr(
|
|||||||
typename,
|
typename,
|
||||||
} => {
|
} => {
|
||||||
let ty = typename
|
let ty = typename
|
||||||
.and_then(|t| symbols.resolve(t))
|
.and_then(|t| symbols.resolve(&t))
|
||||||
.map(|data| data.name.as_str())
|
.map(|data| data.name.as_str())
|
||||||
.map(Type::from_str)
|
.map(Type::from_str)
|
||||||
.transpose()
|
.transpose()
|
||||||
.map_err(|e| SemanticError::new(span, e))?;
|
.map_err(|e| SemanticError::new(span, e))?;
|
||||||
{
|
{
|
||||||
let symbol = symbols.resolve_mut(name).unwrap();
|
let symbol = symbols.resolve_mut(&name).unwrap();
|
||||||
match (symbol.ty, ty) {
|
match (symbol.ty, ty) {
|
||||||
(Some(ty), Some(ty2)) if ty != ty2 => {
|
(Some(ty), Some(ty2)) if ty != ty2 => {
|
||||||
return Err(SemanticError::new(
|
return Err(SemanticError::new(
|
||||||
@@ -147,7 +156,7 @@ fn coerce_types(expr: TypedExpr, symbols: &mut SymbolsTable) -> error::Result<Ty
|
|||||||
TypedExpr::Int { .. } => expr,
|
TypedExpr::Int { .. } => expr,
|
||||||
TypedExpr::Float { .. } => expr,
|
TypedExpr::Float { .. } => expr,
|
||||||
TypedExpr::Var { name, .. } => {
|
TypedExpr::Var { name, .. } => {
|
||||||
let symbol = symbols.resolve_mut(name).unwrap();
|
let symbol = symbols.resolve_mut(&name).unwrap();
|
||||||
|
|
||||||
if symbol.ty.is_none() {
|
if symbol.ty.is_none() {
|
||||||
symbol.ty = Some(Type::Int);
|
symbol.ty = Some(Type::Int);
|
||||||
|
|||||||
@@ -80,11 +80,7 @@ impl TypedExpr {
|
|||||||
match self {
|
match self {
|
||||||
TypedExpr::Int { .. } => Type::Int,
|
TypedExpr::Int { .. } => Type::Int,
|
||||||
TypedExpr::Float { .. } => Type::Float,
|
TypedExpr::Float { .. } => Type::Float,
|
||||||
TypedExpr::Var { name, .. } => symbols
|
TypedExpr::Var { name, .. } => symbols.type_of(name).expect("type not found"),
|
||||||
.resolve(*name)
|
|
||||||
.expect("symbol not found")
|
|
||||||
.ty
|
|
||||||
.expect("type not found"),
|
|
||||||
TypedExpr::BinOp { rhs, .. } => rhs.ty(symbols),
|
TypedExpr::BinOp { rhs, .. } => rhs.ty(symbols),
|
||||||
TypedExpr::IntToFloat { .. } => Type::Float,
|
TypedExpr::IntToFloat { .. } => Type::Float,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,11 +75,11 @@ fn validate_inner(args: ArgsInner) -> Result<ArgsInner, clap::Error> {
|
|||||||
Command::Syn { input, output_tree } => validate_syn(input, output_tree)?,
|
Command::Syn { input, output_tree } => validate_syn(input, output_tree)?,
|
||||||
Command::Sem { input, output_tree } => validate_sem(input, output_tree)?,
|
Command::Sem { input, output_tree } => validate_sem(input, output_tree)?,
|
||||||
Command::Gen {
|
Command::Gen {
|
||||||
mode,
|
|
||||||
input,
|
input,
|
||||||
output,
|
output,
|
||||||
output_symbols,
|
output_symbols,
|
||||||
} => validate_gen(mode, input, output, output_symbols)?,
|
..
|
||||||
|
} => validate_gen(input, output, output_symbols)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(args)
|
Ok(args)
|
||||||
@@ -151,7 +151,6 @@ fn validate_sem(input: &PathBuf, output_tree: &PathBuf) -> Result<(), clap::Erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn validate_gen(
|
fn validate_gen(
|
||||||
_mode: &GenMode,
|
|
||||||
input: &PathBuf,
|
input: &PathBuf,
|
||||||
output: &PathBuf,
|
output: &PathBuf,
|
||||||
output_symbols: &PathBuf,
|
output_symbols: &PathBuf,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ impl fmt::Display for IntermediateValue {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
IntermediateValue::Int { value } => write!(f, "{}", value),
|
IntermediateValue::Int { value } => write!(f, "{}", value),
|
||||||
IntermediateValue::Float { value } => write!(f, "{}", value),
|
IntermediateValue::Float { value } => write!(f, "{:.2}", value),
|
||||||
IntermediateValue::Var { name } => write!(f, "<id,{}>", name),
|
IntermediateValue::Var { name } => write!(f, "<id,{}>", name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ fn to_intermediate_expr_inner(
|
|||||||
let rhs = to_intermediate_expr_inner(*rhs, symbols, intermediate_var_counter, exprs);
|
let rhs = to_intermediate_expr_inner(*rhs, symbols, intermediate_var_counter, exprs);
|
||||||
|
|
||||||
let result = symbols.add(format!("#T{}", intermediate_var_counter));
|
let result = symbols.add(format!("#T{}", intermediate_var_counter));
|
||||||
symbols.resolve_mut(result).unwrap().ty = Some(ty);
|
symbols.resolve_mut(&result).unwrap().ty = Some(ty);
|
||||||
*intermediate_var_counter += 1;
|
*intermediate_var_counter += 1;
|
||||||
|
|
||||||
exprs.push(IntermediateExpr::BinOp {
|
exprs.push(IntermediateExpr::BinOp {
|
||||||
@@ -70,7 +70,7 @@ fn to_intermediate_expr_inner(
|
|||||||
to_intermediate_expr_inner(*value, symbols, intermediate_var_counter, exprs);
|
to_intermediate_expr_inner(*value, symbols, intermediate_var_counter, exprs);
|
||||||
|
|
||||||
let result = symbols.add(format!("#T{}", intermediate_var_counter));
|
let result = symbols.add(format!("#T{}", intermediate_var_counter));
|
||||||
symbols.resolve_mut(result).unwrap().ty = Some(ty);
|
symbols.resolve_mut(&result).unwrap().ty = Some(ty);
|
||||||
*intermediate_var_counter += 1;
|
*intermediate_var_counter += 1;
|
||||||
|
|
||||||
exprs.push(IntermediateExpr::IntToFloat { result, value });
|
exprs.push(IntermediateExpr::IntToFloat { result, value });
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pub struct SymbolData {
|
|||||||
pub id: Symbol,
|
pub id: Symbol,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub ty: Option<Type>,
|
pub ty: Option<Type>,
|
||||||
|
pub temporary: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SymbolData {
|
impl Display for SymbolData {
|
||||||
@@ -26,6 +27,10 @@ impl Display for SymbolData {
|
|||||||
builder.field("type", &ty);
|
builder.field("type", &ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.temporary {
|
||||||
|
builder.field("temporary", &self.temporary);
|
||||||
|
}
|
||||||
|
|
||||||
builder.finish()
|
builder.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,6 +62,7 @@ impl SymbolsTable {
|
|||||||
id: Symbol(self.next_id),
|
id: Symbol(self.next_id),
|
||||||
name: symbol,
|
name: symbol,
|
||||||
ty: None,
|
ty: None,
|
||||||
|
temporary: false,
|
||||||
});
|
});
|
||||||
self.next_id += 1;
|
self.next_id += 1;
|
||||||
|
|
||||||
@@ -70,10 +76,10 @@ impl SymbolsTable {
|
|||||||
self.symbols.get(symbol).map(|data| data.id)
|
self.symbols.get(symbol).map(|data| data.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve(&self, symbol: Symbol) -> Option<&SymbolData> {
|
pub fn resolve(&self, symbol: &Symbol) -> Option<&SymbolData> {
|
||||||
self.symbols.iter().find_map(
|
self.symbols.iter().find_map(
|
||||||
|(_name, data)| {
|
|(_name, data)| {
|
||||||
if data.id == symbol {
|
if &data.id == symbol {
|
||||||
Some(data)
|
Some(data)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -82,10 +88,10 @@ impl SymbolsTable {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_mut(&mut self, symbol: Symbol) -> Option<&mut SymbolData> {
|
pub fn resolve_mut(&mut self, symbol: &Symbol) -> Option<&mut SymbolData> {
|
||||||
self.symbols.iter_mut().find_map(
|
self.symbols.iter_mut().find_map(
|
||||||
|(_name, data)| {
|
|(_name, data)| {
|
||||||
if data.id == symbol {
|
if &data.id == symbol {
|
||||||
Some(data)
|
Some(data)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -93,6 +99,14 @@ impl SymbolsTable {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn type_of(&self, symbol: &Symbol) -> Option<Type> {
|
||||||
|
self.resolve(symbol).and_then(|data| data.ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn temporary(&self, symbol: &Symbol) -> Option<bool> {
|
||||||
|
self.resolve(symbol).map(|data| data.temporary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SymbolsTable {
|
impl Default for SymbolsTable {
|
||||||
|
|||||||
18
src/util.rs
18
src/util.rs
@@ -1,7 +1,7 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{typed::TypedExpr, BinOp, UntypedExpr},
|
ast::{typed::TypedExpr, UntypedExpr},
|
||||||
representation::intermediate::IntermediateExpr,
|
representation::intermediate::IntermediateExpr,
|
||||||
symbols::SymbolsTable,
|
symbols::SymbolsTable,
|
||||||
};
|
};
|
||||||
@@ -21,19 +21,7 @@ pub fn print_intermediate_exprs(
|
|||||||
op,
|
op,
|
||||||
rhs,
|
rhs,
|
||||||
} => {
|
} => {
|
||||||
writeln!(
|
writeln!(writer, "{:#} <id,{}>, {}, {}", op, result, lhs, rhs)?;
|
||||||
writer,
|
|
||||||
"{} <id,{}>, {}, {}",
|
|
||||||
match op {
|
|
||||||
BinOp::Add => "add",
|
|
||||||
BinOp::Sub => "sub",
|
|
||||||
BinOp::Mul => "mul",
|
|
||||||
BinOp::Div => "div",
|
|
||||||
},
|
|
||||||
result,
|
|
||||||
lhs,
|
|
||||||
rhs
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +63,7 @@ fn write_typed_expr(
|
|||||||
TypedExpr::Int { value, .. } => writeln!(writer, "<{}>", value),
|
TypedExpr::Int { value, .. } => writeln!(writer, "<{}>", value),
|
||||||
TypedExpr::Float { value, .. } => writeln!(writer, "<{}>", value),
|
TypedExpr::Float { value, .. } => writeln!(writer, "<{}>", value),
|
||||||
TypedExpr::Var { name, .. } => {
|
TypedExpr::Var { name, .. } => {
|
||||||
let ty = symbols.resolve(*name).unwrap().ty.unwrap();
|
let ty = symbols.resolve(name).unwrap().ty.unwrap();
|
||||||
writeln!(writer, "<id,{},{}>", name, ty)
|
writeln!(writer, "<id,{},{}>", name, ty)
|
||||||
}
|
}
|
||||||
TypedExpr::BinOp { lhs, op, rhs, .. } => {
|
TypedExpr::BinOp { lhs, op, rhs, .. } => {
|
||||||
|
|||||||
Reference in New Issue
Block a user