Esempio n. 1
0
        static void getTypeFromName(AST_Node node)
        {
            if (node.result?.dType != null &&
                (node.result.dType.flags & DataType.Flags.UNFINISHED) == 0)
            {
                return;
            }

            if (enclosure.type == NT.MEMBER_TUPLE)
            {
                node.result = operatorGetMember(ref ((AST_Tuple)enclosure.node).membersFrom, node);
                return;
            }

            AST_Symbol name = (AST_Symbol)node;

            name.symbol = enclosure.scope.searchSymbol(name.text);

            if (name.symbol == null)
            {
                throw Jolly.addError(name.location, "The name \"{0}\" does not exist in the current context".fill(name.text));
            }

            name.result = name.symbol.declaration;
        }
Esempio n. 2
0
        static void load(AST_Node node)
        {
            if ((node.result.dKind & ValueKind.ADDRES) == 0)
            {
                return;
            }

            if (node.nodeType == NT.TUPLE)
            {
                node.result = packTuple((AST_Tuple)node, ((DataType_Tuple)node.result.dType));
            }

            AST_Symbol name = node as AST_Symbol;

            if (name.symbol.isGeneric)
            {
            }

            node.result = instructions.Add(new IR_Read {
                target = node.result, dType = node.result.dType
            });
        }
Esempio n. 3
0
        } // parseExpression()

        void parseIdentifier()
        {
            currentTokenKind = TokenKind.VALUE;
            string   name   = token.text;
            AST_Node target = null;     // If function it's the return type otherwhise it's the variable type

            switch (prevTokenKind)
            {
            case TokenKind.VALUE:
                // Pop eventual period and comma operators
                while (operators.Count > 0)
                {
                    pushOperator(operators.Pop());
                }
                target = values.Pop();
                break;

            case TokenKind.SEPARATOR:
                while (contextStack.Peek().kind == Context.Kind.DECLARATION)
                {
                    contextEnd(contextStack.Pop());
                }
                if (defineMode != DefineMode.ARGUMENT &&
                    prevDefinedType != null &&
                    contextStack.Peek().kind == Context.Kind.STATEMENT)
                {
                    target = prevDefinedType;
                    break;
                }
                goto default;

            default:
                var symbol = new AST_Symbol(token.location, null, name)
                {
                    templateArguments = parseTemplateArguments()
                };
                values.Push(symbol);
                ast.Add(symbol);
                return;
            }

            Token nextToken      = tokens[cursor + 1];
            int   startNodeCount = contextStack.Peek().index;

            if (!canDefine)
            {
                throw Jolly.addError(token.location, "Can't define the {0} \"{1}\" here.".fill(
                                         (nextToken.type == TT.PARENTHESIS_OPEN) ? "function" : "variable",
                                         token.text));
            }

            // Declare
            if (nextToken.type == TT.PARENTHESIS_OPEN ||
                nextToken.type == TT.LESS)
            {
                // Function
                if (defineMode != DefineMode.STATEMENT)
                {
                    throw Jolly.addError(token.location, "Can't define the function \"{0}\" here".fill(name));
                }

                DataType_Function functionType  = new DataType_Function();
                AST_Function      functionNode  = new AST_Function(token.location);
                FunctionTable     functionTable = new FunctionTable(scope);

                functionNode.templateArguments = parseTemplate(functionTable);
                nextToken = tokens[cursor + 1];

                functionNode.index  = ast.Count;
                functionNode.symbol = functionTable;
                functionNode.text   = functionType.name = name;
                functionNode.result = functionTable.declaration = new IR_Function {
                    dType = functionType
                };

                scope.addChild(name, functionTable, true);

                ast.Insert(startNodeCount, functionNode);
                functionNode.returnCount = ast.Count - (startNodeCount += 1);         // Skip the function node itself

                cursor += 2;
                new ExpressionParser(parseData, TT.UNDEFINED, functionTable, DefineMode.ARGUMENT, nextToken.partnerIndex)
                .parse(false);

                functionNode.returns         = target;
                functionType.arguments       = new DataType[functionTable.arguments.Count];         // TODO: This is the wrong count, I think
                functionNode.definitionCount = ast.Count - startNodeCount;

                Token brace = tokens[cursor + 1];
                if (brace.type != TT.BRACE_OPEN)
                {
                    throw Jolly.unexpected(brace);
                }

                cursor += 2;         // Skip parenthesis close and brace open
                new ScopeParser(parseData, brace.partnerIndex, functionTable)
                .parse(ScopeParseMethod.BLOCK);
                functionNode.memberCount = ast.Count - startNodeCount;

                terminator = TT.BRACE_CLOSE;         // HACK: stop parsing
                cursor     = brace.partnerIndex - 1;
            }
            else
            {
                // Variable
                AST_Declaration variableNode;

                if (defineMode == DefineMode.MEMBER)
                {
                    var structType = (DataType_Struct)scope.declaration.dType;
                    if (structType.memberMap.ContainsKey(name))
                    {
                        throw Jolly.addError(token.location, "Type {0} already contains a member named {1}".fill(structType.name, name));
                    }
                    structType.memberMap.Add(name, structType.memberMap.Count);

                    variableNode = new AST_Declaration(token.location, target, scope, name);
                }
                else if ((defineMode & (DefineMode.STATEMENT | DefineMode.ARGUMENT)) != 0)
                {
                    Symbol variableSymbol = new Symbol(scope);
                    variableNode = new AST_Declaration(token.location, target);

                    variableSymbol.isGeneric   = (target.nodeType == NT.TEMPLATE_NAME);             //TODO: Fix generic in tuple
                    variableSymbol.defineIndex = defineIndex++;
                    variableNode.symbol        = variableSymbol;
                    variableNode.text          = name;

                    if (defineMode == DefineMode.ARGUMENT)
                    {
                        ((FunctionTable)scope).arguments.Add(name, variableSymbol);
                    }
                    else
                    {
                        scope.addChild(name, variableSymbol);
                    }
                }
                else
                {
                    throw Jolly.addError(token.location, "Can't define the variable \"{0}\" here.".fill(name));
                }

                prevDefinedType = target;
                values.Push(variableNode);
                ast.Add(variableNode);
                contextStack.Push(new Context(ast.Count, Context.Kind.DECLARATION)
                {
                    target = variableNode
                });
            }
        } // parseIdentifier()