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) => {
|
Statement::Let(let_statement) => {
|
||||||
let ir_variable_info = IrVariableInfo::new(
|
let ir_variable_info = IrVariableInfo::new(
|
||||||
let_statement.declared_name_owned(),
|
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
|
let ir_stack_frame_variable_id = self
|
||||||
.env
|
.env
|
||||||
|
|||||||
@ -70,7 +70,7 @@ pub fn lower_to_ir_synthetic_function(
|
|||||||
let type_info_id =
|
let type_info_id =
|
||||||
session.ctx.nodes_to_type_infos()[&expression_statement.expression().node_id()];
|
session.ctx.nodes_to_type_infos()[&expression_statement.expression().node_id()];
|
||||||
let type_info = &session.ctx.type_infos()[type_info_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.take_parameters(),
|
||||||
storage_env.ir_stack_frame_variables.clone(),
|
storage_env.ir_stack_frame_variables.clone(),
|
||||||
storage_env.ir_free_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,
|
blocks,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -290,7 +290,7 @@ fn lower_to_ir_parameters(
|
|||||||
let parameter_type_info = &ctx.type_infos()[parameter_type_info_id];
|
let parameter_type_info = &ctx.type_infos()[parameter_type_info_id];
|
||||||
fn_ctx.storage_env_mut().new_parameter_for(
|
fn_ctx.storage_env_mut().new_parameter_for(
|
||||||
parameter.declared_name(),
|
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()],
|
ctx.nodes_to_symbols()[¶meter.node_id()],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -349,7 +349,7 @@ fn lower_to_ir_let_statement(
|
|||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
fn_ctx.storage_env_mut().new_free_variable_for(
|
fn_ctx.storage_env_mut().new_free_variable_for(
|
||||||
let_statement.declared_name(),
|
let_statement.declared_name(),
|
||||||
to_ir_type_info(type_info),
|
to_ir_type_info(ctx, type_info),
|
||||||
symbol_id,
|
symbol_id,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
@ -384,7 +384,7 @@ fn lower_to_ir_expression_statement(
|
|||||||
let result_type_info = &ctx.type_infos()[result_type_info_id];
|
let result_type_info = &ctx.type_infos()[result_type_info_id];
|
||||||
let t_var_ir_variable_id = fn_ctx
|
let t_var_ir_variable_id = fn_ctx
|
||||||
.storage_env_mut()
|
.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));
|
let ir_statement = IrStatement::Assign(IrAssign::new(t_var_ir_variable_id, ir_operation));
|
||||||
fn_ctx.current_block_statements.push(ir_statement);
|
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 result_type_info = &ctx.type_infos()[result_type_info_id];
|
||||||
let destination_ir_variable = fn_ctx
|
let destination_ir_variable = fn_ctx
|
||||||
.storage_env_mut()
|
.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
|
// make assign statement to destination temp var
|
||||||
let ir_assign = IrAssign::new(destination_ir_variable.clone(), ir_operation);
|
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 result_type_info = &ctx.type_infos()[result_type_info_id];
|
||||||
let destination_ir_variable = fn_ctx
|
let destination_ir_variable = fn_ctx
|
||||||
.storage_env_mut()
|
.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);
|
let ir_assign = IrAssign::new(destination_ir_variable.clone(), ir_operation);
|
||||||
|
|
||||||
// push the statement which does the multiply by negative one
|
// 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 return_type_info = &ctx.type_infos()[return_type_info_id];
|
||||||
let t_var_ir_variable = fn_ctx
|
let t_var_ir_variable = fn_ctx
|
||||||
.storage_env_mut()
|
.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
|
// assign call to temp var, return temp var expression
|
||||||
let ir_operation = IrOperation::Call(ir_call);
|
let ir_operation = IrOperation::Call(ir_call);
|
||||||
|
|||||||
@ -1,9 +1,17 @@
|
|||||||
use crate::ir::ir_type_info::IrTypeInfo;
|
use crate::ir::ir_type_info::IrTypeInfo;
|
||||||
|
use crate::semantic_analysis::analysis_context::AnalysisContext;
|
||||||
use crate::semantic_analysis::type_info::TypeInfo;
|
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 {
|
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::Int => IrTypeInfo::Int,
|
||||||
TypeInfo::Double => IrTypeInfo::Double,
|
TypeInfo::Double => IrTypeInfo::Double,
|
||||||
TypeInfo::Void => IrTypeInfo::Void,
|
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 {
|
match return_type_info {
|
||||||
TypeInfo::String | TypeInfo::Int | TypeInfo::Double => {
|
TypeInfo::Instance(_) | TypeInfo::Int | TypeInfo::Double => {
|
||||||
Some(to_ir_type_info(return_type_info))
|
Some(to_ir_type_info(ctx, return_type_info))
|
||||||
}
|
}
|
||||||
TypeInfo::Void => None,
|
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() {
|
let return_type_info = match function.return_type() {
|
||||||
None => TypeInfo::Void,
|
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);
|
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);
|
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 {
|
match declared_name {
|
||||||
"Any" => TypeInfo::Any,
|
"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,
|
"Int" => TypeInfo::Int,
|
||||||
"Double" => TypeInfo::Double,
|
"Double" => TypeInfo::Double,
|
||||||
"Void" => TypeInfo::Void,
|
"Void" => TypeInfo::Void,
|
||||||
@ -52,7 +58,7 @@ fn collect_and_get_parameter_type_info_ids(
|
|||||||
) -> Vec<TypeInfoId> {
|
) -> Vec<TypeInfoId> {
|
||||||
let mut parameter_type_info_ids: Vec<TypeInfoId> = Vec::new();
|
let mut parameter_type_info_ids: Vec<TypeInfoId> = Vec::new();
|
||||||
for parameter in parameters {
|
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);
|
let type_info_id = ctx.insert_type_info(type_info);
|
||||||
parameter_type_info_ids.push(type_info_id);
|
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);
|
collect_and_get_parameter_type_info_ids(extern_function.parameters(), ctx);
|
||||||
|
|
||||||
let return_type_info =
|
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 return_type_info_id = ctx.insert_type_info(return_type_info);
|
||||||
|
|
||||||
let function_type_info = TypeInfo::Function(FunctionTypeInfo::new(
|
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 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());
|
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 =
|
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());
|
ctx.insert_type_info_for_node(result_type_info, binary_expression.node_id());
|
||||||
} else {
|
} else {
|
||||||
let op_name = match binary_expression.op() {
|
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::analysis_context::AnalysisContext;
|
||||||
use crate::semantic_analysis::type_info::TypeInfo;
|
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 {
|
match op {
|
||||||
BinaryOperation::Multiply
|
BinaryOperation::Multiply
|
||||||
| BinaryOperation::Divide
|
| BinaryOperation::Divide
|
||||||
| BinaryOperation::Modulo
|
| BinaryOperation::Modulo
|
||||||
| BinaryOperation::Subtract => are_numbers(left, right),
|
| 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::LeftShift
|
||||||
| BinaryOperation::RightShift
|
| BinaryOperation::RightShift
|
||||||
| BinaryOperation::BitwiseAnd
|
| BinaryOperation::BitwiseAnd
|
||||||
@ -25,21 +30,35 @@ fn are_numbers(t0: &TypeInfo, t1: &TypeInfo) -> bool {
|
|||||||
is_number(t0) && is_number(t1)
|
is_number(t0) && is_number(t1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn are_numbers_or_strings(t0: &TypeInfo, t1: &TypeInfo) -> bool {
|
fn are_numbers_or_strings(ctx: &AnalysisContext, t0: &TypeInfo, t1: &TypeInfo) -> bool {
|
||||||
(is_number(t0) || matches!(t0, TypeInfo::String))
|
(is_number(t0) || is_string(ctx, t0)) && (is_number(t1) || is_string(ctx, t1))
|
||||||
&& (is_number(t1) || matches!(t1, TypeInfo::String))
|
}
|
||||||
|
|
||||||
|
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 {
|
fn are_ints(t0: &TypeInfo, t1: &TypeInfo) -> bool {
|
||||||
matches!(t0, TypeInfo::Int) && matches!(t1, TypeInfo::Int)
|
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 {
|
match op {
|
||||||
BinaryOperation::Multiply => numbers_binary_result(left, right),
|
BinaryOperation::Multiply => numbers_binary_result(left, right),
|
||||||
BinaryOperation::Divide => TypeInfo::Double, // okay for now
|
BinaryOperation::Divide => TypeInfo::Double, // okay for now
|
||||||
BinaryOperation::Modulo => numbers_binary_result(left, right), // same properties as multiplication
|
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::Subtract => numbers_binary_result(left, right),
|
||||||
BinaryOperation::LeftShift
|
BinaryOperation::LeftShift
|
||||||
| BinaryOperation::RightShift
|
| 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 {
|
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::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::Int => TypeInfo::Int,
|
||||||
TypeInfo::Double => TypeInfo::Double,
|
TypeInfo::Double => TypeInfo::Double,
|
||||||
TypeInfo::String => TypeInfo::String,
|
|
||||||
TypeInfo::__Error => TypeInfo::__Error,
|
TypeInfo::__Error => TypeInfo::__Error,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
},
|
},
|
||||||
TypeInfo::Double => match right {
|
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::Int | TypeInfo::Double => TypeInfo::Double,
|
||||||
TypeInfo::String => TypeInfo::String,
|
|
||||||
TypeInfo::__Error => TypeInfo::__Error,
|
TypeInfo::__Error => TypeInfo::__Error,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
},
|
},
|
||||||
TypeInfo::String => TypeInfo::String,
|
|
||||||
TypeInfo::__Error => TypeInfo::__Error,
|
TypeInfo::__Error => TypeInfo::__Error,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user