예제 #1
0
        private HVMVariable GetVariable(SyntaxNode owner)
        {
            GetNextTokenWithTypeCheck(HVMTokenId.VarKeyword);
            HVMToken    name    = GetNextTokenWithTypeCheck(HVMTokenId.LiteralIdentifier);
            HVMType     varType = GetDataType();
            HVMVariable var     = new HVMVariable(owner);

            var.VarType = varType;
            var.Name    = name.Value;
            return(var);
        }
예제 #2
0
        /// <summary>
        /// Gets the data-type after a type identifier token.
        /// </summary>
        /// <returns>All the information about the data type (pointer, array, type, name)</returns>
        public HVMType GetDataType()
        {
            GetNextTokenWithTypeCheck(HVMTokenId.TypeIdentifier);
            HVMType dataType = new HVMType();
            // Check for pointer label
            HVMToken token = GetNextToken();

            if (token.Id == HVMTokenId.PointerIdentifier)
            {
                dataType.IsPointer = true; // Mark as pointer
                token = GetNextToken();
            }
            else // Not a pointer
            {
                dataType.IsPointer = false;
            }

            // Make sure it is what we expect it to be.
            if (token.Id != HVMTokenId.LiteralIdentifier)
            {
                ThrowSyntaxParseError(token, "Expected data type got " + token.Id + " at ");
            }

            string dataTypeRaw = token.Value.ToLower();

            if (dataTypeRaw.Equals("int"))
            {
                dataType.Type = HVMTypes.Int;
            }
            else if (dataTypeRaw.Equals("string"))
            {
                dataType.Type = HVMTypes.String;
            }
            else if (dataTypeRaw.Equals("float"))
            {
                dataType.Type = HVMTypes.Float;
            }
            else // Assume it is meaning a user defined data type at the moment. (Cannot validate yet as it is a multi-stage process.)
            {
                dataType.Type = HVMTypes.Struct;
                dataType.Name = token.Value;
            }

            // Check if it is an array. (:$int[] is the most complex format basically.)
            if (PeekNextToken().Id == HVMTokenId.OpenSquareBracket)
            {
                GetNextTokenWithTypeCheck(HVMTokenId.OpenSquareBracket);
                GetNextTokenWithTypeCheck(HVMTokenId.CloseSquareBracket);
                dataType.IsArray = true;
            }

            return(dataType);
        }
예제 #3
0
        public SyntaxTree(List <HVMToken> Tokens, string source)
        {
            _ProgramNode = new SyntaxNode(null);
            this._Tokens = Tokens;
            this._Source = source;
            // Create tree from tokens.

            HVMToken token;

            while ((token = GetNextToken()) != null)
            {
                if (token.Id == HVMTokenId.FuncKeyword)
                {
                    // The following forms of functions we expect.
                    // func:<$>type name(argument-block) (code-block)
                    // func name(argument-block) (code-block) - this has no return type (void)
                    // func:type operator(argument-block) (code-block) - does this HAVE to have a type for all overloaddable operators?

                    HVMType type = null;

                    // It has a type identifier.
                    if (PeekNextToken().Id == HVMTokenId.TypeIdentifier)
                    {
                        type = GetDataType();
                    }
                    else // No type, assume void
                    {
                        type      = new HVMType();
                        type.Type = HVMTypes.Void;
                    }

                    // No type identifier means it doesn't return anything.

                    // This could also be an overloaddable operator too.
                    HVMToken nameOrOperator = GetNextToken();

                    HVMFunc funcSignature = null; // Technically the owner is the program body.

                    if (nameOrOperator.Id == HVMTokenId.LiteralIdentifier)
                    {
                        funcSignature      = new HVMFunc(_ProgramNode);
                        funcSignature.Name = nameOrOperator.Value;
                    }
                    else
                    {
                        funcSignature = new HVMOperatorFunc(_ProgramNode);
                        foreach (HVMTokenId overloadable in _OverloadableOperations)
                        {
                            if (nameOrOperator.Id == overloadable)
                            {
                                (funcSignature as HVMOperatorFunc).Operator = nameOrOperator.Id;
                                break;
                            }
                        }
                        if ((funcSignature as HVMOperatorFunc).Operator == null)
                        {
                            ThrowSyntaxParseError(nameOrOperator, "Cannot overload that operator ");
                        }
                    }

                    funcSignature.ReturnType = type;

                    // Start checking for parameters.
                    GetNextTokenWithTypeCheck(HVMTokenId.OpenParenthesis);

                    if (PeekNextToken().Id == HVMTokenId.CloseParenthesis)
                    {
                        GetNextTokenWithTypeCheck(HVMTokenId.CloseParenthesis);
                        // No parameters in the function.
                        funcSignature.Parameters.Clear();                        // Make sure it is empty.
                    }
                    else if (PeekNextToken().Id == HVMTokenId.LiteralIdentifier) // Parameters.
                    {
                        do
                        {
                            // Swollow the term seperator.
                            if (PeekNextToken().Id == HVMTokenId.TermSeperator)
                            {
                                GetNextTokenWithTypeCheck(HVMTokenId.TermSeperator);
                            }
                            // Get the parameter name and type.
                            HVMToken paramName = GetNextTokenWithTypeCheck(HVMTokenId.LiteralIdentifier);
                            HVMType  paramType = GetDataType();

                            // Function owns the parameters.
                            HVMVariable parameter = new HVMVariable(funcSignature);
                            parameter.Name    = paramName.Value;
                            parameter.VarType = paramType;
                            funcSignature.Parameters.Add(parameter);
                        } while (PeekNextToken().Id == HVMTokenId.TermSeperator);
                        GetNextTokenWithTypeCheck(HVMTokenId.CloseParenthesis);
                    }
                    else
                    {
                        HVMToken wrongToken = GetNextToken();
                        ThrowSyntaxParseError(wrongToken, "Unexpected token in function signature " + wrongToken.Id + ", expected either parameters or ) ");
                    }

                    funcSignature.FunctionBody = new SyntaxNode(funcSignature);
                    // Main function body code, currently not parsing.
                    GetNextTokenWithTypeCheck(HVMTokenId.OpenParenthesis);
                    GetNextTokenWithTypeCheck(HVMTokenId.CloseParenthesis);

#if DEBUG
                    if (funcSignature is HVMOperatorFunc)
                    {
                        Console.WriteLine((funcSignature as HVMOperatorFunc).ToString());
                    }
                    else
                    {
                        Console.WriteLine(funcSignature.ToString());
                    }
#endif
                    // Add the function to the program.
                    _ProgramNode.SubNodes.Add(funcSignature);
                }
                else if (token.Id == HVMTokenId.StructKeyword) // Parse struct.
                {
                    HVMStruct newStruct = new HVMStruct(_ProgramNode);

                    HVMToken name = GetNextTokenWithTypeCheck(HVMTokenId.LiteralIdentifier);
                    newStruct.Name = name.Value;
                    GetNextTokenWithTypeCheck(HVMTokenId.OpenParenthesis);
                    // The members of the struct.
                    do
                    {
                        // Swollow the term seperator.
                        if (PeekNextToken().Id == HVMTokenId.TermSeperator)
                        {
                            GetNextTokenWithTypeCheck(HVMTokenId.TermSeperator);
                        }
                        // Get the parameter name and type.
                        HVMToken paramName = GetNextTokenWithTypeCheck(HVMTokenId.LiteralIdentifier);
                        HVMType  paramType = GetDataType();

                        // Function owns the parameters.
                        HVMVariable parameter = new HVMVariable(newStruct);
                        parameter.Name    = paramName.Value;
                        parameter.VarType = paramType;
                        newStruct.Parameters.Add(parameter);
                    } while (PeekNextToken().Id == HVMTokenId.TermSeperator);

                    GetNextTokenWithTypeCheck(HVMTokenId.CloseParenthesis);

                    Console.WriteLine("Struct name=" + newStruct.Name + " parameters=" + newStruct.Parameters.Count);

                    _ProgramNode.SubNodes.Add(newStruct);
                }
            }
        }