public void Visit(SymFunc symbol)
        {
            if (symbol is PredefinedSymFunc)
            {
                return;
            }

            var name       = symbol.Name;
            var returnType = symbol.ReturnType.Name;

            var paramsList = new StringBuilder();
            var isFirst    = true;

            foreach (var p in symbol.Parameters)
            {
                if (!isFirst)
                {
                    paramsList.Append(", ");
                }
                else
                {
                    isFirst = false;
                }

                switch (p.LocType)
                {
                case SymVar.SymLocTypeEnum.OutParameter:
                    paramsList.Append("out ");
                    break;

                case SymVar.SymLocTypeEnum.VarParameter:
                    paramsList.Append("var ");
                    break;

                case SymVar.SymLocTypeEnum.ConstParameter:
                    paramsList.Append("const ");
                    break;
                }
                paramsList.Append($"{p.Name}:{p.Type.Name}");
            }

            var type = $"function({paramsList}): {returnType}";

            UpdateNameColumnLength(name.Length);
            UpdateTypeColumnLength(type.Length);

            _entries.Add(new KeyValuePair <string, string>(name, type));
        }
예제 #2
0
 public SymFuncConst(string name, SymFunc funcType, SymLocTypeEnum locType) : base(name, funcType, locType)
 {
     FuncType = funcType;
 }
예제 #3
0
        public SymFunc RequireFunction(Token token, SymFunc funcSym, List <ExprNode> args)
        {
            var argc = args.Count;
            var parc = funcSym.Parameters.Count;

            if (argc != parc)
            {
                throw new WrongArgumentsNumberException(parc, argc, token.Lexeme, token.Line, token.Column);
            }

            for (var i = 0; i < argc; i++)
            {
                var currParameter = funcSym.Parameters[i];
                var curArgument   = args[i];

                switch (funcSym.Parameters[i].LocType)
                {
                case SymVar.SymLocTypeEnum.Global:
                case SymVar.SymLocTypeEnum.Local:
                    throw new WrongParameterTypeException();

                case SymVar.SymLocTypeEnum.Parameter:

                    if (currParameter.Type is OpenArray openArray)
                    {
                        if (!(curArgument.Type is SymArray argArr) || !IsTypesEqual(openArray.InnerType, argArr.Type))
                        {
                            var t = ExprNode.GetClosestToken(curArgument);
                            throw new IncompatibleTypesException(currParameter.Type, curArgument.Type, t.Lexeme,
                                                                 t.Line, t.Column);
                        }

                        args[i] = curArgument;
                        break;
                    }

                    RequireCast(currParameter.Type, ref curArgument);
                    args[i] = curArgument;
                    break;

                case SymVar.SymLocTypeEnum.VarParameter:
                    if (currParameter.Type is OpenArray openArrayVar)
                    {
                        if (!(curArgument.Type is SymArray))
                        {
                            var t = ExprNode.GetClosestToken(curArgument);
                            throw new IncompatibleTypesException(curArgument.Type, currParameter.Type,
                                                                 t.Lexeme, t.Line, t.Column);
                        }
                        break;
                    }

                    if (!IsTypesEqual(curArgument.Type, currParameter.Type))
                    {
                        var t = ExprNode.GetClosestToken(curArgument);
                        throw new IncompatibleTypesException(curArgument.Type, currParameter.Type,
                                                             t.Lexeme, t.Line, t.Column);
                    }

                    break;

                case SymVar.SymLocTypeEnum.OutParameter:
                case SymVar.SymLocTypeEnum.ConstParameter:
                    throw new NotImplementedException();

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(funcSym);
        }