Fix String adding without needing to add trait machinery (yet).
This commit is contained in:
parent
f0f377e44e
commit
10579e2ad2
@ -105,7 +105,10 @@ impl SyntheticFunctionSession {
|
||||
Statement::Let(let_statement) => {
|
||||
let ir_variable_info = IrVariableInfo::new(
|
||||
let_statement.declared_name_owned(),
|
||||
to_ir_type_info(self.ctx.get_type_info_for_node(let_statement.node_id())),
|
||||
to_ir_type_info(
|
||||
&self.ctx,
|
||||
self.ctx.get_type_info_for_node(let_statement.node_id()),
|
||||
),
|
||||
);
|
||||
let ir_stack_frame_variable_id = self
|
||||
.env
|
||||
|
||||
@ -70,7 +70,7 @@ pub fn lower_to_ir_synthetic_function(
|
||||
let type_info_id =
|
||||
session.ctx.nodes_to_type_infos()[&expression_statement.expression().node_id()];
|
||||
let type_info = &session.ctx.type_infos()[type_info_id];
|
||||
return_type_info_to_ir_type_info(type_info)
|
||||
return_type_info_to_ir_type_info(session.ctx(), type_info)
|
||||
}
|
||||
};
|
||||
|
||||
@ -275,7 +275,7 @@ fn lower_to_ir_function(function: &Function, ctx: &AnalysisContext) -> IrFunctio
|
||||
storage_env.take_parameters(),
|
||||
storage_env.ir_stack_frame_variables.clone(),
|
||||
storage_env.ir_free_variables.clone(),
|
||||
return_type_info_to_ir_type_info(return_type_info),
|
||||
return_type_info_to_ir_type_info(ctx, return_type_info),
|
||||
blocks,
|
||||
)
|
||||
}
|
||||
@ -290,7 +290,7 @@ fn lower_to_ir_parameters(
|
||||
let parameter_type_info = &ctx.type_infos()[parameter_type_info_id];
|
||||
fn_ctx.storage_env_mut().new_parameter_for(
|
||||
parameter.declared_name(),
|
||||
to_ir_type_info(parameter_type_info),
|
||||
to_ir_type_info(ctx, parameter_type_info),
|
||||
ctx.nodes_to_symbols()[¶meter.node_id()],
|
||||
);
|
||||
}
|
||||
@ -349,7 +349,7 @@ fn lower_to_ir_let_statement(
|
||||
.unwrap_or_else(|| {
|
||||
fn_ctx.storage_env_mut().new_free_variable_for(
|
||||
let_statement.declared_name(),
|
||||
to_ir_type_info(type_info),
|
||||
to_ir_type_info(ctx, type_info),
|
||||
symbol_id,
|
||||
)
|
||||
});
|
||||
@ -384,7 +384,7 @@ fn lower_to_ir_expression_statement(
|
||||
let result_type_info = &ctx.type_infos()[result_type_info_id];
|
||||
let t_var_ir_variable_id = fn_ctx
|
||||
.storage_env_mut()
|
||||
.new_t_var(to_ir_type_info(result_type_info));
|
||||
.new_t_var(to_ir_type_info(ctx, result_type_info));
|
||||
|
||||
let ir_statement = IrStatement::Assign(IrAssign::new(t_var_ir_variable_id, ir_operation));
|
||||
fn_ctx.current_block_statements.push(ir_statement);
|
||||
@ -482,7 +482,7 @@ fn lower_expression_to_ir_expression(
|
||||
let result_type_info = &ctx.type_infos()[result_type_info_id];
|
||||
let destination_ir_variable = fn_ctx
|
||||
.storage_env_mut()
|
||||
.new_t_var(to_ir_type_info(result_type_info));
|
||||
.new_t_var(to_ir_type_info(ctx, result_type_info));
|
||||
|
||||
// make assign statement to destination temp var
|
||||
let ir_assign = IrAssign::new(destination_ir_variable.clone(), ir_operation);
|
||||
@ -506,7 +506,7 @@ fn lower_expression_to_ir_expression(
|
||||
let result_type_info = &ctx.type_infos()[result_type_info_id];
|
||||
let destination_ir_variable = fn_ctx
|
||||
.storage_env_mut()
|
||||
.new_t_var(to_ir_type_info(result_type_info));
|
||||
.new_t_var(to_ir_type_info(ctx, result_type_info));
|
||||
let ir_assign = IrAssign::new(destination_ir_variable.clone(), ir_operation);
|
||||
|
||||
// push the statement which does the multiply by negative one
|
||||
@ -524,7 +524,7 @@ fn lower_expression_to_ir_expression(
|
||||
let return_type_info = &ctx.type_infos()[return_type_info_id];
|
||||
let t_var_ir_variable = fn_ctx
|
||||
.storage_env_mut()
|
||||
.new_t_var(to_ir_type_info(return_type_info));
|
||||
.new_t_var(to_ir_type_info(ctx, return_type_info));
|
||||
|
||||
// assign call to temp var, return temp var expression
|
||||
let ir_operation = IrOperation::Call(ir_call);
|
||||
|
||||
@ -1,9 +1,17 @@
|
||||
use crate::ir::ir_type_info::IrTypeInfo;
|
||||
use crate::semantic_analysis::analysis_context::AnalysisContext;
|
||||
use crate::semantic_analysis::type_info::TypeInfo;
|
||||
|
||||
pub fn to_ir_type_info(sa_type_info: &TypeInfo) -> IrTypeInfo {
|
||||
pub fn to_ir_type_info(ctx: &AnalysisContext, sa_type_info: &TypeInfo) -> IrTypeInfo {
|
||||
match sa_type_info {
|
||||
TypeInfo::String => IrTypeInfo::String,
|
||||
TypeInfo::Instance(instance_type_info) => {
|
||||
let symbol = &ctx.symbols()[instance_type_info.class_symbol_id()];
|
||||
if symbol.unwrap_class_symbol().fqn() == "core::String" {
|
||||
IrTypeInfo::String
|
||||
} else {
|
||||
todo!("Non-string Instance types")
|
||||
}
|
||||
}
|
||||
TypeInfo::Int => IrTypeInfo::Int,
|
||||
TypeInfo::Double => IrTypeInfo::Double,
|
||||
TypeInfo::Void => IrTypeInfo::Void,
|
||||
@ -13,12 +21,15 @@ pub fn to_ir_type_info(sa_type_info: &TypeInfo) -> IrTypeInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn return_type_info_to_ir_type_info(return_type_info: &TypeInfo) -> Option<IrTypeInfo> {
|
||||
pub fn return_type_info_to_ir_type_info(
|
||||
ctx: &AnalysisContext,
|
||||
return_type_info: &TypeInfo,
|
||||
) -> Option<IrTypeInfo> {
|
||||
match return_type_info {
|
||||
TypeInfo::String | TypeInfo::Int | TypeInfo::Double => {
|
||||
Some(to_ir_type_info(return_type_info))
|
||||
TypeInfo::Instance(_) | TypeInfo::Int | TypeInfo::Double => {
|
||||
Some(to_ir_type_info(ctx, return_type_info))
|
||||
}
|
||||
TypeInfo::Void => None,
|
||||
_ => panic!(),
|
||||
_ => panic!("BUG! Unknown return_type_info: {:?}", return_type_info),
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ fn collect_types_function(function: &Function, ctx: &mut AnalysisContext) {
|
||||
|
||||
let return_type_info = match function.return_type() {
|
||||
None => TypeInfo::Void,
|
||||
Some(type_use) => declared_name_to_type_info(type_use.declared_name()),
|
||||
Some(type_use) => declared_name_to_type_info(ctx, type_use.declared_name()),
|
||||
};
|
||||
let return_type_info_id = ctx.insert_type_info(return_type_info);
|
||||
|
||||
@ -35,10 +35,16 @@ fn collect_types_function(function: &Function, ctx: &mut AnalysisContext) {
|
||||
ctx.associate_node_and_symbol_to_type(function.node_id(), function_type_info_id);
|
||||
}
|
||||
|
||||
fn declared_name_to_type_info(declared_name: &str) -> TypeInfo {
|
||||
fn declared_name_to_type_info(ctx: &AnalysisContext, declared_name: &str) -> TypeInfo {
|
||||
match declared_name {
|
||||
"Any" => TypeInfo::Any,
|
||||
"String" => TypeInfo::String,
|
||||
"String" => {
|
||||
// todo: resolve this like a normal instance type
|
||||
let symbol_id = ctx
|
||||
.find_symbol_by_fqn("core::String")
|
||||
.expect("Missing core::String from ctx");
|
||||
ctx.type_infos()[symbol_id].clone()
|
||||
}
|
||||
"Int" => TypeInfo::Int,
|
||||
"Double" => TypeInfo::Double,
|
||||
"Void" => TypeInfo::Void,
|
||||
@ -52,7 +58,7 @@ fn collect_and_get_parameter_type_info_ids(
|
||||
) -> Vec<TypeInfoId> {
|
||||
let mut parameter_type_info_ids: Vec<TypeInfoId> = Vec::new();
|
||||
for parameter in parameters {
|
||||
let type_info = declared_name_to_type_info(parameter.type_use().declared_name());
|
||||
let type_info = declared_name_to_type_info(ctx, parameter.type_use().declared_name());
|
||||
let type_info_id = ctx.insert_type_info(type_info);
|
||||
parameter_type_info_ids.push(type_info_id);
|
||||
|
||||
@ -67,7 +73,7 @@ fn collect_types_extern_function(extern_function: &ExternFunction, ctx: &mut Ana
|
||||
collect_and_get_parameter_type_info_ids(extern_function.parameters(), ctx);
|
||||
|
||||
let return_type_info =
|
||||
declared_name_to_type_info(extern_function.return_type().declared_name());
|
||||
declared_name_to_type_info(ctx, extern_function.return_type().declared_name());
|
||||
let return_type_info_id = ctx.insert_type_info(return_type_info);
|
||||
|
||||
let function_type_info = TypeInfo::Function(FunctionTypeInfo::new(
|
||||
|
||||
@ -177,9 +177,9 @@ fn resolve_types_binary_expression(
|
||||
let lhs_type_info = ctx.get_type_info_for_node(binary_expression.lhs().node_id());
|
||||
let rhs_type_info = ctx.get_type_info_for_node(binary_expression.rhs().node_id());
|
||||
|
||||
if are_binary_op_compatible(binary_expression.op(), lhs_type_info, rhs_type_info) {
|
||||
if are_binary_op_compatible(ctx, binary_expression.op(), lhs_type_info, rhs_type_info) {
|
||||
let result_type_info =
|
||||
binary_op_result(binary_expression.op(), lhs_type_info, rhs_type_info);
|
||||
binary_op_result(ctx, binary_expression.op(), lhs_type_info, rhs_type_info);
|
||||
ctx.insert_type_info_for_node(result_type_info, binary_expression.node_id());
|
||||
} else {
|
||||
let op_name = match binary_expression.op() {
|
||||
|
||||
@ -2,13 +2,18 @@ use crate::ast::binary_expression::BinaryOperation;
|
||||
use crate::semantic_analysis::analysis_context::AnalysisContext;
|
||||
use crate::semantic_analysis::type_info::TypeInfo;
|
||||
|
||||
pub fn are_binary_op_compatible(op: &BinaryOperation, left: &TypeInfo, right: &TypeInfo) -> bool {
|
||||
pub fn are_binary_op_compatible(
|
||||
ctx: &AnalysisContext,
|
||||
op: &BinaryOperation,
|
||||
left: &TypeInfo,
|
||||
right: &TypeInfo,
|
||||
) -> bool {
|
||||
match op {
|
||||
BinaryOperation::Multiply
|
||||
| BinaryOperation::Divide
|
||||
| BinaryOperation::Modulo
|
||||
| BinaryOperation::Subtract => are_numbers(left, right),
|
||||
BinaryOperation::Add => are_numbers_or_strings(left, right),
|
||||
BinaryOperation::Add => are_numbers_or_strings(ctx, left, right),
|
||||
BinaryOperation::LeftShift
|
||||
| BinaryOperation::RightShift
|
||||
| BinaryOperation::BitwiseAnd
|
||||
@ -25,21 +30,35 @@ fn are_numbers(t0: &TypeInfo, t1: &TypeInfo) -> bool {
|
||||
is_number(t0) && is_number(t1)
|
||||
}
|
||||
|
||||
fn are_numbers_or_strings(t0: &TypeInfo, t1: &TypeInfo) -> bool {
|
||||
(is_number(t0) || matches!(t0, TypeInfo::String))
|
||||
&& (is_number(t1) || matches!(t1, TypeInfo::String))
|
||||
fn are_numbers_or_strings(ctx: &AnalysisContext, t0: &TypeInfo, t1: &TypeInfo) -> bool {
|
||||
(is_number(t0) || is_string(ctx, t0)) && (is_number(t1) || is_string(ctx, t1))
|
||||
}
|
||||
|
||||
fn is_string(ctx: &AnalysisContext, type_info: &TypeInfo) -> bool {
|
||||
match type_info {
|
||||
TypeInfo::Instance(instance_type_info) => {
|
||||
let class_symbol = &ctx.symbols()[instance_type_info.class_symbol_id()];
|
||||
class_symbol.unwrap_class_symbol().fqn() == "core::String"
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn are_ints(t0: &TypeInfo, t1: &TypeInfo) -> bool {
|
||||
matches!(t0, TypeInfo::Int) && matches!(t1, TypeInfo::Int)
|
||||
}
|
||||
|
||||
pub fn binary_op_result(op: &BinaryOperation, left: &TypeInfo, right: &TypeInfo) -> TypeInfo {
|
||||
pub fn binary_op_result(
|
||||
ctx: &AnalysisContext,
|
||||
op: &BinaryOperation,
|
||||
left: &TypeInfo,
|
||||
right: &TypeInfo,
|
||||
) -> TypeInfo {
|
||||
match op {
|
||||
BinaryOperation::Multiply => numbers_binary_result(left, right),
|
||||
BinaryOperation::Divide => TypeInfo::Double, // okay for now
|
||||
BinaryOperation::Modulo => numbers_binary_result(left, right), // same properties as multiplication
|
||||
BinaryOperation::Add => add_result(left, right),
|
||||
BinaryOperation::Add => add_result(ctx, left, right),
|
||||
BinaryOperation::Subtract => numbers_binary_result(left, right),
|
||||
BinaryOperation::LeftShift
|
||||
| BinaryOperation::RightShift
|
||||
@ -67,22 +86,40 @@ fn numbers_binary_result(left: &TypeInfo, right: &TypeInfo) -> TypeInfo {
|
||||
}
|
||||
}
|
||||
|
||||
fn add_result(left: &TypeInfo, right: &TypeInfo) -> TypeInfo {
|
||||
fn add_result(ctx: &AnalysisContext, left: &TypeInfo, right: &TypeInfo) -> TypeInfo {
|
||||
match left {
|
||||
TypeInfo::Instance(left_instance_type_info) => {
|
||||
if is_string(ctx, left) {
|
||||
TypeInfo::Instance(left_instance_type_info.clone())
|
||||
} else {
|
||||
todo!("Adding with non-String, non-number types")
|
||||
}
|
||||
}
|
||||
TypeInfo::Int => match right {
|
||||
TypeInfo::Instance(right_instance_type_info) => {
|
||||
if is_string(ctx, right) {
|
||||
TypeInfo::Instance(right_instance_type_info.clone())
|
||||
} else {
|
||||
todo!("Adding with non-String, non-number types")
|
||||
}
|
||||
}
|
||||
TypeInfo::Int => TypeInfo::Int,
|
||||
TypeInfo::Double => TypeInfo::Double,
|
||||
TypeInfo::String => TypeInfo::String,
|
||||
TypeInfo::__Error => TypeInfo::__Error,
|
||||
_ => panic!(),
|
||||
},
|
||||
TypeInfo::Double => match right {
|
||||
TypeInfo::Instance(right_instance_type_info) => {
|
||||
if is_string(ctx, right) {
|
||||
TypeInfo::Instance(right_instance_type_info.clone())
|
||||
} else {
|
||||
todo!("Adding with non-String, non-number types")
|
||||
}
|
||||
}
|
||||
TypeInfo::Int | TypeInfo::Double => TypeInfo::Double,
|
||||
TypeInfo::String => TypeInfo::String,
|
||||
TypeInfo::__Error => TypeInfo::__Error,
|
||||
_ => panic!(),
|
||||
},
|
||||
TypeInfo::String => TypeInfo::String,
|
||||
TypeInfo::__Error => TypeInfo::__Error,
|
||||
_ => panic!(),
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user