Beispiel #1
0
        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();
            }
        }