public override AstNode VisitMainClass(MainClass ast) { //main class must be the first class. Debug.Assert(m_types.Count == 0); var name = ast.Name.Value; var mainclassType = new CodeClassType() { Name = name, IsStatic = true }; m_types.Add(mainclassType); ast.Type = mainclassType; return ast; }
public override AstNode VisitClassDecl(ClassDecl ast) { var name = ast.Name.Value; if (m_types.Contains(name)) { m_errorManager.AddError(c_SE_TypeNameDuplicates, ast.Name.Span, name); return ast; } var classType = new CodeClassType() { Name = name }; m_types.Add(classType); ast.Type = classType; return ast; }
public override AstNode VisitClassDecl(ClassDecl ast) { var name = ast.Name.Content; if (m_types.Contains(name)) { AddError(c_SE_TypeNameDuplicates, ast.Name.Span, name); return(ast); } var classType = new CodeClassType() { Name = name }; m_types.Add(classType); ast.Type = classType; return(ast); }
public override AstNode VisitMainClass(MainClass ast) { m_currentType = ast.Type as CodeClassType; Debug.Assert(m_currentType.Methods.Count == 0); Debug.Assert(m_currentType.StaticMethods.Count == 1); m_currentMethod = m_currentType.StaticMethods[0]; m_currentVariableIndex = 0; m_currentMethodParameters = new VariableCollection <Parameter>() { new Parameter() { Name = ast.ArgName.Content, Type = ArrayType.StrArray } }; m_currentMethodVariables = new VariableCollection <VariableInfo>(); foreach (var statement in ast.Statements) { Visit(statement); } return(ast); }
private void ResolveMethod(Call ast, CodeClassType targetType) { if (targetType == null) { AddError(c_SE_MethodMissing, ast.Method.MethodName.Span, ast.Method.MethodName.Content); ast.ExpressionType = PrimaryType.Unknown; return; } // step 1: collect candidates from current type var candidates = (from m in targetType.Methods where String.Equals(m.Name, ast.Method.MethodName.Content, StringComparison.InvariantCulture) && m.Parameters.Count == ast.Arguments.Count select m).ToArray(); if (candidates.Length == 0) { ResolveMethod(ast, targetType.BaseType); return; } // step 2: remove unqualifed candidates List <Method> qualifiedCandidates = new List <Method>(); foreach (var candidate in candidates) { bool isQualified = true; for (int i = 0; i < candidate.Parameters.Count; i++) { if (!candidate.Parameters[i].Type.IsAssignableFrom(ast.Arguments[i].ExpressionType)) { isQualified = false; break; } } if (isQualified) { qualifiedCandidates.Add(candidate); } } if (qualifiedCandidates.Count == 0) { ResolveMethod(ast, targetType.BaseType); return; } // step 3: choose a "best" one if (qualifiedCandidates.Count > 1) { var comparer = new MethodOverloadingComparer(ast.Arguments); qualifiedCandidates.Sort(comparer); var firstCandidate = qualifiedCandidates[0]; var secondCandidate = qualifiedCandidates[1]; if (comparer.Compare(firstCandidate, secondCandidate) < 0) { //choose first as the best one ast.Method.MethodInfo = firstCandidate; ast.ExpressionType = firstCandidate.ReturnType; } else { //ambiguous between first & second AddError(c_SE_MethodAmbiguous, ast.Method.MethodName.Span, firstCandidate.GetSignatureString(), secondCandidate.GetSignatureString()); ast.ExpressionType = PrimaryType.Unknown; } } else { ast.Method.MethodInfo = qualifiedCandidates[0]; ast.ExpressionType = qualifiedCandidates[0].ReturnType; } }
private void ResolveMethod(Call ast, CodeClassType targetType) { if (targetType == null) { m_errorManager.AddError(c_SE_MethodMissing, ast.Method.MethodName.Span, ast.Method.MethodName.Value); ast.ExpressionType = PrimaryType.Unknown; return; } // step 1: collect candidates from current type var candidates = (from m in targetType.Methods where String.Equals(m.Name, ast.Method.MethodName.Value, StringComparison.InvariantCulture) && m.Parameters.Count == ast.Arguments.Count select m).ToArray(); if (candidates.Length == 0) { ResolveMethod(ast, targetType.BaseType); return; } // step 2: remove unqualifed candidates List<Method> qualifiedCandidates = new List<Method>(); foreach (var candidate in candidates) { bool isQualified = true; for (int i = 0; i < candidate.Parameters.Count; i++) { if (!candidate.Parameters[i].Type.IsAssignableFrom(ast.Arguments[i].ExpressionType)) { isQualified = false; break; } } if (isQualified) qualifiedCandidates.Add(candidate); } if (qualifiedCandidates.Count == 0) { ResolveMethod(ast, targetType.BaseType); return; } // step 3: choose a "best" one if (qualifiedCandidates.Count > 1) { var comparer = new MethodOverloadingComparer(ast.Arguments); qualifiedCandidates.Sort(comparer); var firstCandidate = qualifiedCandidates[0]; var secondCandidate = qualifiedCandidates[1]; if (comparer.Compare(firstCandidate, secondCandidate) < 0) { //choose first as the best one ast.Method.MethodInfo = firstCandidate; ast.ExpressionType = firstCandidate.ReturnType; } else { //ambiguous between first & second m_errorManager.AddError(c_SE_MethodAmbiguous, ast.Method.MethodName.Span, firstCandidate.GetSignatureString(), secondCandidate.GetSignatureString()); ast.ExpressionType = PrimaryType.Unknown; } } else { ast.Method.MethodInfo = qualifiedCandidates[0]; ast.ExpressionType = qualifiedCandidates[0].ReturnType; } }
private VariableInfo ResolveField(CodeClassType type, Lexeme identifier) { //step1, see current class if (type.Fields.Contains(identifier.Value)) { return type.Fields[identifier.Value]; } //step2, see base class if (m_currentType.BaseType != null) { return ResolveField(m_currentType.BaseType, identifier); } m_errorManager.AddError(c_SE_VariableDeclMissing, identifier.Span, identifier.Value); return null; }
public override AstNode VisitMainClass(MainClass ast) { m_currentType = ast.Type as CodeClassType; Debug.Assert(m_currentType.Methods.Count == 0); Debug.Assert(m_currentType.StaticMethods.Count == 1); m_currentMethod = m_currentType.StaticMethods[0]; m_currentVariableIndex = 0; m_currentMethodParameters = new VariableCollection<Parameter>() { new Parameter() { Name = ast.ArgName.Value, Type = ArrayType.StrArray } }; m_currentMethodVariables = new VariableCollection<VariableInfo>(); foreach (var statement in ast.Statements) { Visit(statement); } return ast; }
public override AstNode VisitClassDecl(ClassDecl ast) { m_currentType = ast.Type as CodeClassType; foreach (var method in ast.Methods) { Visit(method); } return ast; }