Пример #1
0
        public static BaseNameTableItem ByName(string name,
                                               Scope scope,
                                               RoutineNameTableItem currentRoutine,
                                               SlangCustomType currentType,
                                               ModuleNameTable moduleItem,
                                               SourceCodeTable table,
                                               Dictionary <string, bool> checkDefinitions)
        {
            var result = scope.FindVariable(name); // заходим во внешние блоки

            if (result == null)
            {
                // мы сейчас находимся в функции?
                if (currentRoutine != null && currentRoutine is { } routine)
                {
                    // в методе?
                    if (currentRoutine is MethodNameTableItem method)
                    {
                        // может это имя this метода?
                        if (method.NameOfThis == name)
                        {
                            return(new VariableNameTableItem {
                                IsConstant = false, Type = currentType, Name = name
                            });
                        }
                    }
                    // неважно, в функции или методе -- проверяем его параметры
                    foreach (var param in routine.Params)
                    {
                        if (param.Name == name)
                        {
                            return(new VariableNameTableItem {
                                IsConstant = false, Type = param.TypeArg.Type, Name = name
                            });
                        }
                    }
                }

                if (moduleItem.Fields.ContainsKey(name) && (checkDefinitions != null ? checkDefinitions[name] : true))
                {
                    return(moduleItem.Fields[name]);
                }
                // либо это процедура-функция (взять все сигнатуры) ?
                if (moduleItem.Routines.ContainsKey(name) && (checkDefinitions != null ? checkDefinitions[name] : true))
                {
                    return(moduleItem.Routines[name]);
                }
                // ну либо это другой модуль?
                if (moduleItem.ImportedModules.Contains(name) || name == moduleItem.ModuleData.Name)
                {
                    return(table.Modules[name]);
                }

                return(null);
                // иначе ничего не остается кроме как отдать пустоту
            }

            return(result);
        }
Пример #2
0
 public override object VisitTypeDecl([NotNull] SLangGrammarParser.TypeDeclContext context)
 {
     checkDefinitions[context.Id().GetText()] = true;
     currentType = Table.FindClass(ModuleData.Name, context.Id().GetText()).TypeIdent;
     base.VisitTypeDecl(context);
     currentType = null;
     return(null);
 }
Пример #3
0
 public override object VisitProcedureDecl([NotNull] SLangGrammarParser.ProcedureDeclContext context)
 {
     InitRoutines(context.thisHeader(), context.Id().GetText());
     TranslateRoutines(context.statementSeq());
     currentRoutine = null;
     currentType    = null;
     return(null);
 }
Пример #4
0
 public override object VisitModuleStatementsSeq([NotNull] SLangGrammarParser.ModuleStatementsSeqContext context)
 {
     // state -- work in module statements
     currentRoutine = null;
     inProgramBlock = true;
     currentType    = null;
     //ToDo checks expressions in fields
     return(base.VisitModuleStatementsSeq(context));
 }
Пример #5
0
        public override object VisitProcedureDecl([NotNull] SLangGrammarParser.ProcedureDeclContext context)
        {
            var symbol = context.Id().Symbol;

            InitializeRoutineStates(context.thisHeader(), symbol);
            CheckParamsNameConflicts(context.thisHeader(), context.routineArgList());
            // some work... need to call visit()?
            Visit(context.statementSeq());
            currentType    = null;
            currentRoutine = null;
            return(null);
        }
Пример #6
0
        public override object VisitFunctionDecl([NotNull] SLangGrammarParser.FunctionDeclContext context)
        {
            // init states, check of abstract methods or imported functions
            // add entries in h & cpp
            // visit sequence

            InitRoutines(context.thisHeader(), context.Id().GetText());
            TranslateRoutines(context.statementSeq());
            currentRoutine = null;
            currentType    = null;
            return(null);
        }
Пример #7
0
        private void InitializeRoutineStates(SLangGrammarParser.ThisHeaderContext context, IToken symbol)
        {
            currentType = context != null?Visit(context.customType()) as SlangCustomType : null;

            if (currentType != null)
            {
                currentRoutine = Table.FindClass(currentType).Methods[symbol.Text];
            }
            else
            {
                currentRoutine = moduleItem.Routines[symbol.Text];
                checkDefinitions[symbol.Text] = true;
            }
        }
        /// <summary>
        /// return custom type for pointer and custom types
        /// </summary>
        /// <param name="type">type</param>
        /// <returns>custom type (if exists), else null</returns>
        private SlangCustomType GetUserType(SlangType type)
        {
            SlangCustomType usedType = null;

            if (type is SlangCustomType t)
            {
                usedType = t;
            }
            else if (type is SlangPointerType pt)
            {
                usedType = pt.PtrType;
            }
            return(usedType);
        }
Пример #9
0
 private void InitRoutines(SLangGrammarParser.ThisHeaderContext thisHeader, string routineName)
 {
     if (thisHeader != null)
     {
         currentType = GetCustomTypeContext(thisHeader.customType());
     }
     if (currentType != null)
     {
         currentRoutine = source.FindClass(currentType).Methods[routineName];
     }
     else
     {
         currentRoutine = currentModule.Routines[routineName];
     }
 }
Пример #10
0
        public override object VisitFunctionDecl([NotNull] SLangGrammarParser.FunctionDeclContext context)
        {
            var symbol = context.Id().Symbol;

            InitializeRoutineStates(context.thisHeader(), symbol);
            CheckParamsNameConflicts(context.thisHeader(), context.routineArgList());

            var result = Visit(context.statementSeq()) as StatementResult;

            // функция, которая не импортируется извне и не является абстрактным методом?
            if (result != null && !result.Returning && currentRoutine.Header == null && !(currentRoutine is MethodNameTableItem method && method.IsAbstract))
            {
                ThrowNotAllCodePathException(file, context.statementSeq().Start);
            }

            currentType    = null;
            currentRoutine = null;
            return(null);
        }
Пример #11
0
        public bool TryFoundClassItemsByName(string name, SlangCustomType classContext, SlangCustomType destType, out BaseNameTableItem item)
        {
            item = null;
            bool result = true;

            // находимся в контексте этого типа
            if (classContext != null && classContext.Equals(destType))
            {
                var classItem = FindClass(destType);
                if (classItem.Methods.ContainsKey(name))
                {
                    item = classItem.Methods[name];
                }
                else if (classItem.Fields.ContainsKey(name))
                {
                    item = classItem.Fields[name];
                }
                else
                {
                    result = false;
                }
            }
            else
            {
                var classItem = FindClass(destType);
                if (classItem.Methods.ContainsKey(name) && classItem.Methods[name].AccessModifier == AccessModifier.Public)
                {
                    item = classItem.Methods[name];
                }
                else if (classItem.Fields.ContainsKey(name) && classItem.Fields[name].AccessModifier == AccessModifier.Public)
                {
                    item = classItem.Fields[name];
                }
                else
                {
                    result = false;
                }
            }

            return(result);
        }
Пример #12
0
 public static void ThrowClassItemNotFoundException(string msg, SlangCustomType typeIdent, FileInfo file, int line, int column) => ThrowException($"Item with name {msg} was not found in class {typeIdent}", file, line, column);
 private void CheckLevelAccessForMethods(MethodNameTableItem method, ITerminalNode routineToken, SlangCustomType classIdent)
 {
     foreach (var item in method.Params)
     {
         var typeArg = item.TypeArg.Type;
         if (typeArg is SlangCustomType || typeArg is SlangPointerType)
         {
             var customType = GetUserType(typeArg);
             var classItem  = Table.Modules[customType.ModuleName].Classes[customType.Name];
             if (classItem.AccessModifier == AccessModifier.Private && !customType.Equals(classIdent))
             {
                 ThrowLevelAccessibilityForRoutineException(routineToken, ModuleData.File, customType.ToString(), method.Name);
             }
         }
     }
     if (method.ReturnType != null)
     {
         if (method.ReturnType is SlangCustomType type)
         {
             var classItem = Table.Modules[type.ModuleName].Classes[type.Name];
             if (classItem.AccessModifier == AccessModifier.Private)
             {
                 ThrowLevelAccessibilityForRoutineException(routineToken, ModuleData.File, type.ToString(), method.Name);
             }
         }
     }
 }
Пример #14
0
 private FileInfo GetFileOfClass(SlangCustomType typeId)
 {
     return(Table.Modules[typeId.ModuleName].ModuleData.File);
 }
Пример #15
0
 public static void ThrowMethodSignatureExistsException(SlangCustomType classData, ITerminalNode name, FileInfo file) => ThrowException($"Method with same signature already exists in class {classData}", file, name.Symbol);
Пример #16
0
 public static void ThrowInvalidUseIncompleteTypeException(SlangCustomType classItem, FileInfo file, IToken symbol) => ThrowException($"Invalid use of incomplete type {classItem}", file, symbol);
Пример #17
0
 public static void ThrowClassNotMarkedAsBaseException(SlangCustomType classItem, FileInfo file, IToken symbol) => ThrowException($"Class {classItem} is not marked as base", file, symbol);
Пример #18
0
 public SlangPointerType(SlangCustomType type)
 {
     PtrType = type;
 }
Пример #19
0
 public static void ThrowClassFieldOverrideException(string fieldName, SlangCustomType baseClass, SlangCustomType derivedClass, FileInfo fileInfo, int line, int column) => throw new CompilerException($"Trying to override field {fieldName} from base class {baseClass} in derived class {derivedClass}", fileInfo, line, column);
Пример #20
0
 public SlangPointerType()
 {
     PtrType = SlangCustomType.Object;
 }
Пример #21
0
 public ClassNameTableItem FindClass(SlangCustomType type)
 {
     return(FindClass(type.ModuleName, type.Name));
 }