diff --git a/src/asg/expr/kind.rs b/src/asg/expr/kind.rs index 5efff1c..2573bf3 100644 --- a/src/asg/expr/kind.rs +++ b/src/asg/expr/kind.rs @@ -42,6 +42,7 @@ pub enum ExprKind { EnumMemberLiteral(Box), ResolvedNamedExpression(Box), Zeroed(Box), + SizeOf(Box), InterpreterSyscall(InterpreterSyscallKind, Vec), } diff --git a/src/ast/expr/kind.rs b/src/ast/expr/kind.rs index 0941c8b..911477f 100644 --- a/src/ast/expr/kind.rs +++ b/src/ast/expr/kind.rs @@ -3,7 +3,11 @@ use super::{ InterpreterSyscall, ShortCircuitingBinaryOperation, StaticMemberCall, StaticMemberValue, StructLiteral, UnaryOperation, While, }; -use crate::{ast::Privacy, name::Name, source_files::Source}; +use crate::{ + ast::{Privacy, Type}, + name::Name, + source_files::Source, +}; use std::ffi::CString; #[derive(Clone, Debug)] @@ -29,6 +33,7 @@ pub enum ExprKind { While(Box), StaticMemberValue(Box), StaticMemberCall(Box), + SizeOf(Box), InterpreterSyscall(Box), } diff --git a/src/lower/expr/mod.rs b/src/lower/expr/mod.rs index 312e937..e2403dc 100644 --- a/src/lower/expr/mod.rs +++ b/src/lower/expr/mod.rs @@ -137,6 +137,9 @@ pub fn lower_expr( Box::new(ir::Type::Void), )))), ExprKind::Call(call) => lower_expr_call(builder, ir_module, expr, function, asg, call), + ExprKind::PolyCall(poly_call) => { + lower_expr_poly_call(builder, ir_module, expr, function, asg, poly_call) + } ExprKind::Variable(variable) => { let pointer_to_variable = lower_variable_to_value(variable.key); let variable_type = lower_type(ir_module, &builder.unpoly(&variable.ty)?, asg)?; @@ -484,6 +487,10 @@ pub fn lower_expr( let ir_type = lower_type(ir_module, &builder.unpoly(ty)?, asg)?; Ok(ir::Value::Literal(Literal::Zeroed(ir_type))) } + ExprKind::SizeOf(ty) => { + let ir_type = lower_type(ir_module, &builder.unpoly(ty)?, asg)?; + Ok(builder.push(ir::Instr::SizeOf(ir_type))) + } ExprKind::InterpreterSyscall(syscall, args) => { let mut values = Vec::with_capacity(args.len()); @@ -493,9 +500,6 @@ pub fn lower_expr( Ok(builder.push(ir::Instr::InterpreterSyscall(*syscall, values))) } - ExprKind::PolyCall(poly_call) => { - lower_expr_poly_call(builder, ir_module, expr, function, asg, poly_call) - } } } diff --git a/src/parser/parse_expr/primary/mod.rs b/src/parser/parse_expr/primary/mod.rs index ee73f66..d73ebd1 100644 --- a/src/parser/parse_expr/primary/mod.rs +++ b/src/parser/parse_expr/primary/mod.rs @@ -7,8 +7,8 @@ mod struct_literal; use super::{super::error::ParseError, is_right_associative, is_terminating_token, Parser}; use crate::{ ast::{ - Block, Conditional, Expr, ExprKind, Integer, TypeKind, UnaryMathOperator, UnaryOperation, - UnaryOperator, While, + Block, Conditional, Expr, ExprKind, Integer, TypeArg, TypeKind, UnaryMathOperator, + UnaryOperation, UnaryOperator, While, }, inflow::Inflow, parser::{array_last, error::ParseErrorKind, parse_util::into_plain_name}, @@ -148,9 +148,17 @@ impl<'a, I: Inflow> Parser<'a, I> { } _ => { if !generics.is_empty() { + // TODO: CLEANUP: Clean up this code if let Some("sizeof") = name.as_plain_str() { - todo!("sizeof operator"); - // Ok(Expr::new(ExprKind::SizeOf(inner), source)) + if let Some(type_arg) = generics.first() { + if let TypeArg::Type(ty) = type_arg { + if generics.len() == 1 { + return Ok( + ExprKind::SizeOf(Box::new(ty.clone())).at(source) + ); + } + } + } } return Err(ParseErrorKind::Other { diff --git a/src/resolve/expr/mod.rs b/src/resolve/expr/mod.rs index dcceae9..bab2d23 100644 --- a/src/resolve/expr/mod.rs +++ b/src/resolve/expr/mod.rs @@ -24,11 +24,15 @@ use super::{ Initialized, ResolveTypeCtx, }; use crate::{ - asg::{self, Asg, CurrentConstraints, Expr, ExprKind, FuncRef, StructRef, TypeKind, TypedExpr}, + asg::{ + self, Asg, CurrentConstraints, Expr, ExprKind, FuncRef, IntegerBits, StructRef, TypeKind, + TypedExpr, + }, ast::{ self, CInteger, CIntegerAssumptions, ConformBehavior, IntegerKnown, Language, Settings, UnaryOperator, }, + ir::IntegerSign, resolve::{ error::ResolveErrorKind, expr::{ @@ -371,6 +375,14 @@ pub fn resolve_expr( ast::ExprKind::StaticMemberCall(static_access_call) => { resolve_static_member_call(ctx, static_access_call) } + ast::ExprKind::SizeOf(ast_type) => { + let ty = ctx.type_ctx().resolve(ast_type)?; + + Ok(TypedExpr::new( + asg::TypeKind::Integer(IntegerBits::Bits64, IntegerSign::Unsigned).at(source), + asg::ExprKind::SizeOf(Box::new(ty)).at(source), + )) + } ast::ExprKind::InterpreterSyscall(info) => { let ast::InterpreterSyscall { kind,