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); }
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); }
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) }); }
//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)); }