1
0
This commit is contained in:
2024-11-10 10:33:06 +03:00
parent f1b89d554b
commit b6c6a3b4b7
6 changed files with 45 additions and 39 deletions

View File

@@ -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,6 +45,14 @@ 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 {
if f.alternate() {
match self {
BinOp::Add => f.write_str("add"),
BinOp::Sub => f.write_str("sub"),
BinOp::Mul => f.write_str("mul"),
BinOp::Div => f.write_str("div"),
}
} else {
match self { match self {
BinOp::Add => f.write_str("+"), BinOp::Add => f.write_str("+"),
BinOp::Sub => f.write_str("-"), BinOp::Sub => f.write_str("-"),
@@ -53,6 +61,7 @@ impl fmt::Display for BinOp {
} }
} }
} }
}
pub fn to_typed_expr(expr: UntypedExpr, symbols: &mut SymbolsTable) -> error::Result<TypedExpr> { pub fn to_typed_expr(expr: UntypedExpr, symbols: &mut SymbolsTable) -> error::Result<TypedExpr> {
let expr = convert_to_typed_expr(expr, symbols)?; let expr = convert_to_typed_expr(expr, symbols)?;
@@ -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);

View File

@@ -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,
} }

View File

@@ -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,

View File

@@ -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 });

View File

@@ -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 {

View File

@@ -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, .. } => {