Пример #1
0
        public override bool VisitAssignmentStatement(QuestScriptParser.AssignmentStatementContext context)
        {
            var success = base.VisitAssignmentStatement(context);

            var identifier         = context.LVal.GetText();
            var variable           = _current.GetVariable(identifier);
            var variableDefined    = variable != null;
            var isMemberAssignment = identifier.Contains(".");

            if (!isMemberAssignment && !variableDefined)
            {
                DeclareLocalVariable(identifier, context.LVal, context.RVal);
            }
            else if (variableDefined && !isMemberAssignment) //do a type check, since we are not declaring but assigning
            {
                //do type checking, since this is not a declaration but an assignment
                var rValueType = TypeInferenceVisitor.Visit(context.RVal);
                var lValueType = TypeInferenceVisitor.Visit(context.LVal);
                if (lValueType != rValueType && !TypeUtil.CanConvert(rValueType, lValueType))
                {
                    Errors.Add(new UnexpectedTypeException(context, lValueType, rValueType, context.RVal,
                                                           "Also, tried to find suitable implicit casting, but didn't find anything."));
                }

                variable.Value = ValueResolverVisitor.Visit(context.RVal);
            }

            return(success);
        }
Пример #2
0
        public override bool VisitForEachStatement(QuestScriptParser.ForEachStatementContext context)
        {
            _current = _current.CreateChild(context); //push
            var enumerationVariableType = TypeInferenceVisitor.Visit(context.enumerationVariable);

            if (enumerationVariableType != ObjectType.List)
            {
                Errors.Add(new UnexpectedTypeException(context, ObjectType.List, enumerationVariableType,
                                                       context.enumerationVariable, "'foreach' can only enumerate on collection types."));
            }

            if (!_current.IsVariableDefined(context.iterationVariable.Text))
            {
                DeclareLocalVariable(context.iterationVariable.Text, context, context.enumerationVariable,
                                     isEnumerationVariable: true);
            }
            else
            {
                Errors.Add(
                    new ConflictingVariableName(context, context.iterationVariable.Text,
                                                "Iteration variable names in 'foreach' statements must not conflict with already defined variables."));
            }

            var success = base.VisitForEachStatement(context);

            _current = _current.Parent; //pop
            return(success);
        }
Пример #3
0
        private void DeclareLocalVariable(string name, ParserRuleContext variableContext,
                                          ParserRuleContext valueContext, bool isEnumerationVariable = false, bool isIterationVariable = false)
        {
            var type = TypeInferenceVisitor.Visit(valueContext);

            _current.LocalVariables.Add(new Variable
            {
                Name = name,
                Type = type,
                IsEnumerationVariable = isEnumerationVariable,
                IsIterationVariable   = isIterationVariable,
                Context = variableContext,
                Value   = ValueResolverVisitor.Visit(valueContext)
            });
        }
Пример #4
0
        //if condition type check - make sure it resolves to boolean type
        public override bool VisitIfStatement(QuestScriptParser.IfStatementContext context)
        {
            var ifConditionExpressionType = TypeInferenceVisitor.Visit(context.condition);

            if (ifConditionExpressionType != ObjectType.Unknown &&
                ifConditionExpressionType != ObjectType.Boolean)
            {
                Errors.Add(new InvalidConditionException(context, "if", context.condition));
            }

            foreach (var elseifCondition in context._elseifConditions)
            {
                var elseIfConditionExpressionType = TypeInferenceVisitor.Visit(elseifCondition);
                if (elseIfConditionExpressionType != ObjectType.Unknown &&
                    elseIfConditionExpressionType != ObjectType.Boolean)
                {
                    Errors.Add(new InvalidConditionException(context, "elseif", elseifCondition));
                }
            }

            return(base.VisitIfStatement(context));
        }
Пример #5
0
 public ScriptEnvironmentBuilder()
 {
     TypeInferenceVisitor = new TypeInferenceVisitor(this);
     ValueResolverVisitor = new ValueResolverVisitor(this);
 }