private static ExpressionNode ParseLiteral(RuleContext rule)
        {
            RuleContext realLiteral = (RuleContext)rule.GetChild(0);

            switch (realLiteral.RuleIndex)
            {
            case CrawlParser.RULE_string_literal:
                return(CrawlSyntaxNode.StringLiteral(realLiteral.SourceInterval, CrawlType.UnspecifiedType, Unescape(realLiteral.GetText())));

            case CrawlParser.RULE_integer_literal:
                return(CrawlSyntaxNode.IntegerLiteral(realLiteral.SourceInterval, CrawlType.UnspecifiedType, int.Parse(realLiteral.GetText())));

            case CrawlParser.RULE_boolean_literal:
                return(CrawlSyntaxNode.BooleanLiteral(realLiteral.SourceInterval, CrawlType.UnspecifiedType, (realLiteral.GetText()) == "true"));

            case CrawlParser.RULE_real_literal:
                return(CrawlSyntaxNode.RealLiteral(realLiteral.SourceInterval, CrawlType.UnspecifiedType, double.Parse(realLiteral.GetText())));

            case CrawlParser.RULE_null_literal:
                return(CrawlSyntaxNode.NullLiteral(realLiteral.SourceInterval, CrawlSimpleType.Tom));

            default:
                throw new NotImplementedException("Strange literal type");
            }
        }
        private static FlowNode ParseIf(RuleContext rule)
        {
            //IF expression INDENT statements DEDENT (ELSE INDENT statements DEDENT)?;
            ExpressionNode expression = ExpressionParser.ParseExpression((RuleContext)rule.GetChild(1));
            BlockNode      trueBlock  = ParseBlockNode((RuleContext)rule.GetChild(3));

            //Pure if
            if (rule.ChildCount == 5)
            {
                return(CrawlSyntaxNode.If(rule.SourceInterval, expression, trueBlock));
            }
            //If Else
            else if (rule.ChildCount == 9)
            {
                BlockNode falseBlock = ParseBlockNode((RuleContext)rule.GetChild(7));
                return(CrawlSyntaxNode.IfElse(rule.SourceInterval, expression, trueBlock, falseBlock));
            }
            //Else if
            else if (rule.ChildCount == 7)
            {
                RuleContext            chain         = (RuleContext)rule.GetChild(6);
                List <CrawlSyntaxNode> blockContents = new List <CrawlSyntaxNode>()
                {
                    ParseIf(chain)
                };
                BlockNode falseBlock = CrawlSyntaxNode.Block(chain.SourceInterval, blockContents);
                return(CrawlSyntaxNode.IfElse(rule.SourceInterval, expression, trueBlock, falseBlock));
            }

            throw new NotImplementedException("if statement with strange argument counts (this is probably else if)");
        }
        private static ExpressionNode ParseCast(RuleContext expression)
        {
            //( LPARENTHESIS type RPARENTHESIS ) * unary_expression
            var             castExpression = (CrawlParser.Cast_expressionContext)expression;
            List <TypeNode> targetTypes    = new List <TypeNode>();

            //Parse every part of the chain of casts. The for-loop works; Trust me.
            for (int i = castExpression.ChildCount - 3; i > 2; i -= 3)
            {
                targetTypes.Add(ParseTreeParser.ParseType((CrawlParser.TypeContext)castExpression.GetChild(i)));
            }

            //Parse the rest of the expression.
            ExpressionNode result = ParseExpression((RuleContext)castExpression.LastChild());

            //Wrap the casts around the rest of the expression one at a time.
            foreach (TypeNode type in targetTypes)
            {
                result = CrawlSyntaxNode.CastExpression(
                    Interval.Invalid, ExpressionType.Cast, CrawlType.UnspecifiedType,
                    type,
                    result
                    );
            }

            return(result);
        }
        private static List <ParameterNode> ParseParameters(CrawlParser.ParametersContext context)
        {
            List <ParameterNode> resutls = new List <ParameterNode>();

            //parameters : LPARENTHESIS (parameter ( ITEM_SEPARATOR parameter )* )?  RPARENTHESIS;
            //parameter : REFERENCE? type IDENTIFIER;
            if (context.ChildCount > 2)
            {
                for (int i = 1; i < context.ChildCount; i = i + 2)
                {
                    IParseTree parameter = context.GetChild(i);
                    //If the parameter has 3 children it starts with a REFERENCE token
                    //Otherwise it starts with the identifier

                    bool isReference = parameter.ChildCount == 3;
                    int  startat     = isReference ? 1 : 0;

                    resutls.Add(
                        CrawlSyntaxNode.Parameter(
                            parameter.SourceInterval,
                            isReference,
                            true,
                            ParseType(
                                (CrawlParser.TypeContext)parameter.GetChild(startat + 0)
                                ),
                            ParseIdentifier(
                                (ITerminalNode)parameter.GetChild(startat + 1)
                                )
                            )
                        );
                }
            }
            return(resutls);
        }
        private static ExpressionNode ParseMultu(RuleContext rule)
        {
            List <ExpressionNode> sources = new List <ExpressionNode>();

            sources.Add(ParseExpression((RuleContext)rule.GetChild(0)));
            ExpressionType type = ParseMultiOp((ITerminalNode)rule.GetChild(1));

            //Operations of same precedence may be chained together. Go through rest of the operator nodes.
            for (int i = 1; i < rule.ChildCount; i += 2)
            {
                ExpressionType newtype = ParseMultiOp((ITerminalNode)rule.GetChild(i));
                if (newtype == type)
                {
                    sources.Add(ParseExpression((RuleContext)rule.GetChild(i + 1)));
                }
                else
                {
                    //TODO: Actually calculate the interval
                    //The expression contained multiple types of operations
                    ExpressionNode newNode = CrawlSyntaxNode.MultiChildExpression(Interval.Invalid, type, CrawlType.UnspecifiedType, sources);
                    sources.Clear();
                    sources.Add(newNode);
                    type = newtype;
                    sources.Add(ParseExpression((RuleContext)rule.GetChild(i + 1)));
                }
            }

            return(CrawlSyntaxNode.MultiChildExpression(rule.SourceInterval, type, CrawlType.UnspecifiedType, sources));
        }
        private static TypeNode GenerateMethodSignature(TypeNode returnType, List <TypeNode> parameterTypes)
        {
            StringBuilder textDef = new StringBuilder();

            textDef.Append(returnType.TypeName);

            textDef.Append('(');

            if (parameterTypes.Count > 0)
            {
                textDef.Append(parameterTypes[0].TypeName);
                for (var i = 1; i < parameterTypes.Count; i++)
                {
                    textDef.Append(", ");
                    textDef.Append(parameterTypes[i].TypeName);
                }
            }

            textDef.Append(')');

            Interval interval;

            if (parameterTypes.Count > 0)
            {
                interval = new Interval(returnType.Interval.a, parameterTypes.Last().Interval.b);    //TODO: Only roughly correct.
            }
            else
            {
                interval = new Interval(returnType.Interval.a, returnType.Interval.b);    //TODO: Only roughly correct.
            }
            TypeNode result = CrawlSyntaxNode.TypeNode(interval, textDef.ToString(), 0, null);

            return(result);
        }
        private static DeclerationNode ParseClassDecleration(RuleContext classPart, ProtectionLevel protectionLevel, Interval interval)
        {
            //The second last child. And one for the zero-indexing.
            int genericParametersIndex = classPart.ChildCount - 2 - 1;

            ITerminalNode tn1 = (ITerminalNode)classPart.GetChild(0);

            ITerminalNode tn2 = (ITerminalNode)classPart.GetChild(1);

            CrawlParser.InheritancesContext baseTypes = classPart.GetChild(2) as CrawlParser.InheritancesContext;

            IEnumerable <IdentifierNode> inheritances = baseTypes == null ? new List <IdentifierNode>() : ParseInheritances(baseTypes);

            CrawlParser.Generic_parametersContext genericParametersContext =
                classPart.GetChild(genericParametersIndex) as CrawlParser.Generic_parametersContext;

            RuleContext body = (RuleContext)classPart.LastChild();

            List <GenericParameterNode> genericParameters = new List <GenericParameterNode>();

            if (genericParametersContext != null)
            {
                genericParameters.AddRange(ParseGenericParameters(genericParametersContext));
            }

            if (tn1.Symbol.Type != CrawlLexer.CLASS)
            {
                throw new CrawlImpossibleStateException("Trying to parse a class that is not a class", interval);
            }

            BlockNode bodyBlock = ParseBlockNode(body);

            return(CrawlSyntaxNode.ClassTypeDecleration(interval, protectionLevel, null, ParseIdentifier(tn2), inheritances, genericParameters, bodyBlock));
        }
        protected override CrawlSyntaxNode VisitMethodDecleration(MethodDeclerationNode methodDecleration)
        {
            var decl = (MethodDeclerationNode)base.VisitMethodDecleration(methodDecleration);

            List <ParameterNode> newParams = new List <ParameterNode>();

            foreach (ParameterNode param in decl.Parameters)
            {
                if (param.Reference) //If it's a reference, don't mess with it.
                {
                    newParams.Add(param);
                }
                else
                {
                    //If there is any risk of side-effects affecting non-ref parameter, don't optimize to ref.
                    var visitor = new CheckSideEffectsOfSingleParameterVisitor(param.Identifier.Value);
                    if (visitor.Visit(methodDecleration.Body))
                    {
                        newParams.Add(param);
                    }
                    else
                    {
                        newParams.Add(CrawlSyntaxNode.Parameter(param.Interval, param.Reference,
                                                                false, param.ParameterType, param.Identifier));
                    }
                }
            }

            return(CrawlSyntaxNode.MethodDecleration(decl.Interval, decl.ProtectionLevel, decl.Scope, decl.MethodSignature,
                                                     newParams, decl.Body, decl.Identifier, decl.GenericParameters));
        }
        protected override CrawlSyntaxNode VisitMultiChildExpression(MultiChildExpressionNode multiChildExpression)
        {
            var expr = (MultiChildExpressionNode)base.VisitMultiChildExpression(multiChildExpression);

            if (!(expr.ExpressionType == ExpressionType.Add ||
                  expr.ExpressionType == ExpressionType.Multiply ||
                  expr.ExpressionType == ExpressionType.ShortCircuitAnd ||
                  expr.ExpressionType == ExpressionType.ShortCircuitOr))
            {
                return(expr);
            }

            List <ExpressionNode> literals = new List <ExpressionNode>();
            List <ExpressionNode> restOfIt = new List <ExpressionNode>();

            foreach (ExpressionNode expression in expr.Arguments)
            {
                var literal = expression as LiteralNode;

                if (literal != null)
                {
                    literals.Add(literal);
                }
                else
                {
                    restOfIt.Add(expression);
                }
            }

            List <ExpressionNode> newArguments = literals.Concat(restOfIt).ToList();

            return(CrawlSyntaxNode.MultiChildExpression(expr.Interval, expr.ExpressionType, expr.ResultType,
                                                        newArguments));
        }
        public static ExpressionNode ParseExpression(RuleContext rule)
        {
            //Literal value.
            if (rule.RuleIndex == CrawlParser.RULE_literal)
            {
                return(ParseLiteral(rule));
            }

            if (rule.RuleIndex == CrawlParser.RULE_atom)
            {
                //Reference to variable by identifier.
                ITerminalNode tn = rule.GetChild(0) as ITerminalNode;
                if (tn != null && tn.Symbol.Type == CrawlLexer.IDENTIFIER)
                {
                    return(CrawlSyntaxNode.Variable(tn.SourceInterval, CrawlType.UnspecifiedType, tn.GetText()));
                }
                //Expression in parentheses. Parse only content, throw out parentheses.
                else if (rule.ChildCount == 3)
                {
                    return(ParseExpression((RuleContext)rule.GetChild(1)));
                }
            }

            //If this is just an intermedite node, proceed to the next one.
            if (rule.ChildCount == 1)
            {
                return(ParseExpression((RuleContext)rule.GetChild(0)));
            }

            //And lastly handle operators.
            switch (rule.RuleIndex)
            {
            case CrawlParser.RULE_postfix_expression:
                return(ParsePostfix(rule));

            case CrawlParser.RULE_array_initialization_expression:
                return(ParseArrayInitialization(rule));

            case CrawlParser.RULE_comparison_expression:
            case CrawlParser.RULE_range_expression:
                return(ParseBinary(rule));

            case CrawlParser.RULE_additive_expression:
            case CrawlParser.RULE_multiplicative_expression:
            case CrawlParser.RULE_and_expression:
            case CrawlParser.RULE_or_expression:
            case CrawlParser.RULE_exponential_expression:
                return(ParseMultu(rule));

            case CrawlParser.RULE_cast_expression:
                return(ParseCast(rule));

            case CrawlParser.RULE_unary_expression:
                return(ParseUnary(rule));

            default:
                throw new NotImplementedException("Some expression type is not handled");
            }
        }
Beispiel #11
0
        public override void Visit(CrawlSyntaxNode node)
        {
            if (node is IScope)
            {
                CheckHides(node);
            }

            base.Visit(node);
        }
        private static FlowNode ParseWhile(RuleContext rule)
        {
            ExpressionNode condition = ExpressionParser.ParseExpression((RuleContext)rule.GetChild(1));
            BlockNode      block     = ParseBlockNode((RuleContext)rule.GetChild(3));

            return(CrawlSyntaxNode.While(rule.SourceInterval, condition, block));

            throw new NotImplementedException();
        }
        public static NamespaceNode FindNameSpace(this CrawlSyntaxNode node)
        {
            CrawlSyntaxNode result = node;

            while (!(result is NamespaceNode) && !(result is TranslationUnitNode))
            {
                result = result.Parent;
            }

            return(result as NamespaceNode);
        }
Beispiel #14
0
        public override void Visit(CrawlSyntaxNode node)
        {
            Indent();
            Lenght = BuildString.Length;
            //AddSpaces(indent);
            BuildString.Append(node.ToString());


            base.Visit(node);
            Dedent();
        }
 private static CrawlSyntaxNode ParseReturn(RuleContext rule)
 {
     if (rule.ChildCount == 3)
     {
         ExpressionNode retvalue = ExpressionParser.ParseExpression((RuleContext)rule.GetChild(1));
         return(CrawlSyntaxNode.ReturnStatement(rule.SourceInterval, retvalue));
     }
     else
     {
         return(CrawlSyntaxNode.ReturnStatement(rule.SourceInterval, null));
     }
 }
        protected override CrawlSyntaxNode VisitBinaryExpression(BinaryExpressionNode binaryExpression)
        {
            BinaryExpressionNode newExpressoinNode = (BinaryExpressionNode)(base.VisitBinaryExpression(binaryExpression));
            CrawlType            leftOperand       = newExpressoinNode.LeftHandSide.ResultType;
            CrawlType            rightOperand      = newExpressoinNode.RightHandSide.ResultType;
            ExpressionType       oprator           = newExpressoinNode.ExpressionType;

            CrawlType       expressionTypeResult = EvaluateBinaryType(leftOperand, oprator, rightOperand);
            CrawlSyntaxNode result = newExpressoinNode.WithResultType(expressionTypeResult);

            return(result);
        }
        private static ExpressionNode ParseArrayInitialization(RuleContext rule)
        {
            // An array initialization is the call of a typeNode's constructor

            TypeNode             type            = ParseTreeParser.ParseType((CrawlParser.TypeContext)rule.GetChild(0));
            ArrayConstructorNode typeConstructor = CrawlSyntaxNode.ArrayConstructor(type.Interval, CrawlType.UnspecifiedType, type);
            // TypeConstructorNode is an ExpressionNode that corresponds to a TypeNode

            IEnumerable <ArgumentNode> arguments = ParseCallTail((RuleContext)rule.GetChild(1)).Select(x => CrawlSyntaxNode.Argument(x.Interval, false, x));

            return(CrawlSyntaxNode.Call(rule.SourceInterval, CrawlType.UnspecifiedType, typeConstructor, arguments));
        }
Beispiel #18
0
        private static LiteralNode FoldTheDreadedAddition(LiteralNode op1, LiteralNode op2)
        {
            Interval interval = new Interval(op1.Interval.a, op2.Interval.b);

            //Aye.
            IntegerLiteralNode int1 = op1 as IntegerLiteralNode;
            IntegerLiteralNode int2 = op2 as IntegerLiteralNode;
            RealLiteralNode    rea1 = op1 as RealLiteralNode;
            RealLiteralNode    rea2 = op2 as RealLiteralNode;
            StringLiteralNode  str1 = op1 as StringLiteralNode;
            StringLiteralNode  str2 = op2 as StringLiteralNode;

            if (int1 != null && int2 != null)
            {
                int result = int1.Value + int2.Value;
                return(CrawlSyntaxNode.IntegerLiteral(interval, CrawlSimpleType.Tal, result));
            }
            if (str1 != null && str2 != null)
            {
                string result = str1.Value + str2.Value;
                return(CrawlSyntaxNode.StringLiteral(interval, CrawlSimpleType.Tekst, result));
            }
            if (rea1 != null && rea2 != null)
            {
                double result = rea1.Value + rea2.Value;
                return(CrawlSyntaxNode.RealLiteral(interval, CrawlSimpleType.Kommatal, result));
            }
            //Hvis de er forskellige, se om a kan tildeles til b, hvis ja,  konverter a til b's type
            //Hvis stadig ikke se om b kan tildeles til a, hvis ja, konverter b til a's type
            if (str1 != null)
            {
                string result = str1.Value + (int2?.Value.ToString() ?? rea2?.Value.ToString(CultureInfo.GetCultureInfo("en-GB")));
                return(CrawlSyntaxNode.StringLiteral(interval, CrawlSimpleType.Tekst, result));
            }
            if (str2 != null)
            {
                string result = (int1?.Value.ToString() ?? rea1?.Value.ToString(CultureInfo.GetCultureInfo("en-GB"))) + str2.Value;
                return(CrawlSyntaxNode.StringLiteral(interval, CrawlSimpleType.Tekst, result));
            }
            if (rea1 != null)
            {
                double result = rea1.Value + int2.Value;
                return(CrawlSyntaxNode.RealLiteral(interval, CrawlSimpleType.Kommatal, result));
            }
            if (rea2 != null)
            {
                double result = int1.Value + rea2.Value;
                return(CrawlSyntaxNode.RealLiteral(interval, CrawlSimpleType.Kommatal, result));
            }
            throw new NullReferenceException();
        }
        /// <summary>
        /// Parse single import node
        /// </summary>
        public static ImportNode ParseImportNode(RuleContext rule)
        {
            StringBuilder path = new StringBuilder();


            path.Append(rule.GetChild(1).GetText());
            //Stride 2 to avoid dots.
            for (int i = 3; i < rule.ChildCount; i = i + 2)
            {
                path.Append(".");
                path.Append(rule.GetChild(i).GetText());
            }

            return(CrawlSyntaxNode.Import(rule.SourceInterval, path.ToString()));
        }
        protected override CrawlSyntaxNode VisitUnaryExpression(UnaryExpressionNode unaryExpression)
        {
            CrawlSyntaxNode     expr      = base.VisitUnaryExpression(unaryExpression);
            UnaryExpressionNode unaryExpr = expr as UnaryExpressionNode;

            if (unaryExpr == null)
            {
                return(expr);
            }

            OptimizationsWereMade = true;

            ExpressionNode tar = unaryExpr.Target;

            return(FoldUnary(tar, unaryExpression.ExpressionType));
        }
        private static DeclerationNode ParseMethodDecleration(RuleContext methodContext, ProtectionLevel protectionLevel, Interval interval)
        {
            //Return Type
            TypeNode returnType =
                ParseType((CrawlParser.TypeContext)methodContext.GetChild(0));

            //Parameters TODO: Use parameter names.
            List <ParameterNode> parameters =
                ParseParameters((CrawlParser.ParametersContext)methodContext.GetChild(1));

            TypeNode methodSignature = GenerateMethodSignature(returnType, parameters.Select(foo => foo.ParameterType).ToList());

            //Generic Parameters
            List <GenericParameterNode> genericParameters
                = new List <GenericParameterNode>();


            CrawlParser.Generic_parametersContext genericsContext =
                methodContext.GetChild(2) as CrawlParser.Generic_parametersContext;

            if (genericsContext != null)
            {
                genericParameters.AddRange(ParseGenericParameters(genericsContext));
            }

            //Body
            RuleContext bodyContext = (RuleContext)methodContext.LastChild().GetChild(1);
            BlockNode   body        = ParseBlockNode(bodyContext);

            //Identifier
            int           identifierIndex    = methodContext.ChildCount - 2 - 1; //Identifier is always second last. And then one for the zero-indexed arrays.
            ITerminalNode identifierTerminal =
                (ITerminalNode)methodContext.GetChild(identifierIndex);
            IdentifierNode identifier = ParseIdentifier(identifierTerminal);

            //Combine it all.
            return(CrawlSyntaxNode.MethodDecleration(
                       interval,
                       protectionLevel,
                       null, /*scope has no stuff yet*/
                       methodSignature,
                       parameters,
                       body,
                       identifier,
                       genericParameters
                       ));
        }
        public static ExpressionNode ParseSideEffectStatement(RuleContext rule)
        {
            ITerminalNode eos = (ITerminalNode)rule.GetChild(2);

            if (eos.Symbol.Type != CrawlLexer.END_OF_STATEMENT)
            {
                throw new CrawlImpossibleStateException($"Method call not ending {nameof(CrawlLexer.END_OF_STATEMENT)}", rule.SourceInterval);
            }

            RuleContext toCall     = (RuleContext)rule.GetChild(0);
            RuleContext invocation = (RuleContext)rule.GetChild(1);

            List <ArgumentNode> args   = ParseArgumentList(invocation).ToList();
            ExpressionNode      target = ParseExpression(toCall);

            return(CrawlSyntaxNode.Call(rule.SourceInterval, CrawlType.UnspecifiedType, target, args));
        }
        public static TypeNode ParseType(CrawlParser.TypeContext type)
        {
            // No array specified -> the type is not an array
            var array = type.GetChild(1) as CrawlParser.Array_typeContext ?? type.GetChild(2) as CrawlParser.Array_typeContext;

            if (array == null)
            {
                return(CrawlSyntaxNode.TypeNode(type.SourceInterval, type.GetText(), 0, null));
            }

            // Array is specified -> We count the dimensions.
            //// Then we remove the trailing [] from the type definition, because we now keep track of it within the dimensions?? IS THIS NECESSARY?
            int arrayDimensions = CountTypeArrayDimensions(array);

            // string dimensionsAsString = $"[{StringExtensions.AddStringForeach(",", arrayDimensions)}]";
            // string typeText = type.GetText();
            // string typeWithoutLastArray = typeText.Remove(typeText.LastIndexOf(dimensionsAsString, StringComparison.Ordinal));
            return(CrawlSyntaxNode.TypeNode(type.SourceInterval, type.GetText(), arrayDimensions, null));
        }
        private static NamespaceNode ParseNamespace(RuleContext nameSpace)
        {
            StringBuilder path = new StringBuilder();

            if (nameSpace.ChildCount != 0)
            {
                //Child 0 is reserved word "pakke", and is discarded.


                path.Append(nameSpace.GetChild(1).GetText());
                //Stride 2 to avoid dots.
                for (int i = 3; i < nameSpace.ChildCount; i = i + 2)
                {
                    path.Append(".");
                    path.Append(nameSpace.GetChild(i).GetText());
                }
            }
            return(CrawlSyntaxNode.Namespace(nameSpace.SourceInterval, path.ToString()));
        }
        private static FlowNode ParseFor(RuleContext rule)
        {
            //FOR type IDENTIFIER FOR_LOOP_SEPERATOR expression INDENT statements DEDENT
            ITerminalNode forNode = (ITerminalNode)rule.GetChild(0);

            CrawlParser.TypeContext typeNode       = (CrawlParser.TypeContext)rule.GetChild(1);
            ITerminalNode           identifierNode = (ITerminalNode)rule.GetChild(2);
            ITerminalNode           serperatorNode = (ITerminalNode)rule.GetChild(3);
            RuleContext             expression     = (RuleContext)rule.GetChild(4);
            ITerminalNode           indent         = (ITerminalNode)rule.GetChild(5);
            RuleContext             blockCtx       = (RuleContext)rule.GetChild(6);
            ITerminalNode           dedent         = (ITerminalNode)rule.GetChild(7);

            TypeNode       type      = ParseType(typeNode);
            ExpressionNode iteratior = ExpressionParser.ParseExpression(expression);
            BlockNode      block     = ParseBlockNode(blockCtx);

            return(CrawlSyntaxNode.ForLoop(rule.SourceInterval, null, type, ParseIdentifier(identifierNode), iteratior, block));
        }
Beispiel #26
0
        private static LiteralNode FoldBinary(LiteralNode op1, ExpressionType expressionType, LiteralNode op2)
        {
            var val1 = GetNumber(op1);
            var val2 = GetNumber(op2);

            bool result;

            switch (expressionType)
            {
            case ExpressionType.Greater:
                result = val1 > val2;
                break;

            case ExpressionType.GreaterEqual:
                result = val1 >= val2;
                break;

            case ExpressionType.Less:
                result = val1 < val2;
                break;

            case ExpressionType.LessEqual:
                result = val1 <= val2;
                break;

            case ExpressionType.Equal:
                result = Math.Abs(val1 - val2) < Double.Epsilon;
                break;

            case ExpressionType.NotEqual:
                result = Math.Abs(val1 - val2) > Double.Epsilon;
                break;

            default:
                throw new Exception("Wait this isn't a binary operator!");
            }

            Interval interval = new Interval(op1.Interval.a, op2.Interval.b);

            return(CrawlSyntaxNode.BooleanLiteral(interval, CrawlSimpleType.Bool, result));
        }
        private static CrawlSyntaxNode ParseAssignment(RuleContext rule)
        {
            ExpressionNode target = ExpressionParser.ParseExpression((RuleContext)rule.GetChild(0));

            if (rule.GetChild(1) is CrawlParser.Subfield_expressionContext)
            {
                CrawlParser.Subfield_expressionContext subfield = (CrawlParser.Subfield_expressionContext)rule.GetChild(1);

                IdentifierNode sub = CrawlSyntaxNode.Identifier(subfield.GetChild(1).SourceInterval, subfield.GetChild(1).GetText());
                target = CrawlSyntaxNode.MemberAccess(subfield.SourceInterval, CrawlType.UnspecifiedType, target, sub);
            }
            else if (rule.GetChild(1) is CrawlParser.Index_expressionContext)
            {
                RuleContext idx = (RuleContext)rule.GetChild(1);
                target = CrawlSyntaxNode.Index(idx.SourceInterval, CrawlType.UnspecifiedType, target, ExpressionParser.ParseArgumentList(idx));
            }

            ExpressionNode value = ExpressionParser.ParseExpression((RuleContext)rule.GetChild(rule.ChildCount - 2));

            return(CrawlSyntaxNode.Assignment(rule.SourceInterval, target, value));
        }
        protected override CrawlSyntaxNode VisitBinaryExpression(BinaryExpressionNode binaryExpression)
        {
            CrawlSyntaxNode      expr       = base.VisitBinaryExpression(binaryExpression);
            BinaryExpressionNode binaryExpr = expr as BinaryExpressionNode;

            if (binaryExpr == null)
            {
                return(expr);
            }

            LiteralNode lhs = binaryExpr.LeftHandSide as LiteralNode;
            LiteralNode rhs = binaryExpr.RightHandSide as LiteralNode;

            if (lhs == null || rhs == null || binaryExpr.ExpressionType == ExpressionType.Range)
            {
                return(expr);
            }

            OptimizationsWereMade = true;
            return(FoldBinary(lhs, binaryExpr.ExpressionType, rhs));
        }
        private static DeclerationNode ParseVariableDecleration(RuleContext classPart, ProtectionLevel protectionLevel, Interval interval)
        {
            //This is the whole variable decleration. First the type, then individual variables of that type, with an optional initialization value
            //Each individual identifier is parsed in ParseSingleVariable
            ITerminalNode eos = classPart.LastChild() as ITerminalNode;

            if (eos == null || eos.Symbol.Type != CrawlLexer.END_OF_STATEMENT)
            {
                throw new NotImplementedException("Something strange happened");
            }

            TypeNode type = ParseType((CrawlParser.TypeContext)classPart.GetChild(0));

            return(CrawlSyntaxNode.VariableDecleration(
                       interval,
                       protectionLevel,
                       type,
                       classPart
                       .AsEdgeTrimmedIEnumerable()
                       .OfType <CrawlParser.Variable_declContext>()
                       .Select(ParseSingleVariable)));
        }
        public static TranslationUnitNode ParseTranslationUnit(CrawlParser.Translation_unitContext translationUnit)
        {
            CrawlParser.Import_directivesContext imports =
                (CrawlParser.Import_directivesContext)translationUnit.GetChild(0);

            CrawlParser.Namespace_declarationContext nameSpace =
                (CrawlParser.Namespace_declarationContext)translationUnit.GetChild(1);

            CrawlParser.StatementsContext statements =
                (CrawlParser.StatementsContext)translationUnit.GetChild(2);


            IEnumerable <ImportNode> importNodes = ParseImports(imports);

            //Add the "No namespace" namespace
            importNodes = importNodes.Concat(CrawlSyntaxNode.Import(Interval.Invalid, "").AsSingleIEnumerable());
            NamespaceNode namespaceNode = ParseNamespace(nameSpace);   //Forts�t herfra.
            BlockNode     rootBlock     = ParseBlockNode(statements);


            return(CrawlSyntaxNode.TranslationUnit(translationUnit.SourceInterval, null, importNodes, namespaceNode, rootBlock));
        }