private static bool InternalTryCompileExpression( ExpressionSyntax syntax, CompiledMethod method, BasicBlockBuilder builder, INameResolver nameResolver, IDiagnosticSink diagnostics, out Temporary value) { value = default; if (syntax is IntegerLiteralSyntax integer) { // Decide the type for the literal // TODO: There is for now only support for int32 and uint32, and only because the smallest int32 should be // TODO: representable. This logic should be updated once multiple integer types officially exist. if (integer.Value > uint.MaxValue) { diagnostics.Add(DiagnosticCode.IntegerConstantOutOfBounds, syntax.Position, integer.Value.ToString(), SimpleType.Int32.TypeName); return(false); } else if (integer.Value > int.MaxValue) { // TODO: This does not work for anything else than int32 minimum value = Temporary.FromConstant(SimpleType.UInt32, ConstantValue.SignedInteger((long)integer.Value)); return(true); } else { value = Temporary.FromConstant(SimpleType.Int32, ConstantValue.SignedInteger((long)integer.Value)); return(true); } } else if (syntax is BooleanLiteralSyntax boolean) { value = Temporary.FromConstant(SimpleType.Bool, ConstantValue.Bool(boolean.Value)); return(true); } else if (syntax is IdentifierSyntax named) { if (!nameResolver.TryResolveVariable(named.Name, out var valueNumber)) { diagnostics.Add(DiagnosticCode.VariableNotFound, named.Position, named.Name); return(false); } value = Temporary.FromLocal(method.Values[valueNumber].Type, (ushort)valueNumber); return(true); } else if (syntax is UnaryExpressionSyntax unary) { if (!InternalTryCompileExpression(unary.InnerExpression, method, builder, nameResolver, diagnostics, out var inner)) { return(false); } return(TryCompileUnary(unary, inner, method, builder, diagnostics, out value)); } else if (syntax is BinaryExpressionSyntax binary) { if (!InternalTryCompileExpression(binary.Left, method, builder, nameResolver, diagnostics, out var left) || !InternalTryCompileExpression(binary.Right, method, builder, nameResolver, diagnostics, out var right)) { return(false); } return(TryCompileBinary(binary, left, right, method, builder, diagnostics, out value)); } else if (syntax is FunctionCallSyntax call) { return(TryCompileCall(call, method, builder, diagnostics, nameResolver, out value)); } else { throw new NotImplementedException(); } }