Beispiel #1
0
        public void ThrowSyntaxParseError(HVMToken token, string message)
        {
            if (token == null)
            {
                throw new Exception(message);
            }
            else
            {
                string sourceSample = "";

                if (token.SourceIndex + 10 < _Source.Length)
                {
                    sourceSample = _Source.Substring(token.SourceIndex, 10);
                }
                else
                {
                    sourceSample = _Source.Substring(token.SourceIndex, _Source.Length - token.SourceIndex);
                }

                int pos = sourceSample.IndexOf(_Source[token.SourceIndex]);
                sourceSample = sourceSample.Insert(pos, "[");
                sourceSample = sourceSample.Insert(pos + 2, "]");

                throw new Exception(message + " " + sourceSample + "...");
            }
        }
Beispiel #2
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);
        }
Beispiel #3
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);
        }
Beispiel #4
0
        private SyntaxNode GetStatement(SyntaxNode owner)
        {
            // Gets the next statement in the tokenized program.
            HVMToken token = PeekNextToken();

            if (token.Id == HVMTokenId.IfKeyword)
            {
            }


            return(null);
        }
Beispiel #5
0
        public HVMToken GetNextTokenWithTypeCheck(HVMTokenId id)
        {
            HVMToken token = GetNextToken();

            if (token != null)
            {
                if (token.Id != id)
                {
                    ThrowSyntaxParseError(token, "Expected " + id + " got " + token.Id + " at ");
                }
            }
            else
            {
                ThrowSyntaxParseError(null, "Expected " + id + " and got nothing!");
            }

            return(token);
        }
Beispiel #6
0
        public List <HVMToken> GetTokens()
        {
            _Source = _Source.Replace("\n", "").Replace("\t", "").Replace("\r", "");

            Console.WriteLine(_Source);

            // These are ordered in a specific way.

            while (_Index < _Source.Length)
            {
                bool     found       = false;
                HVMToken foundToken  = null;
                char     currentChar = _Source[_Index];

                foreach (KeyValuePair <string, HVMToken> tokens in Tokenizer._AvailableTokens)
                {
                    // Look for keywords and operators in the available tokens.
                    if (ContainsString(tokens.Key, _Index))
                    {
                        // Create the token with the id and stuff.

                        foundToken             = new HVMToken();
                        foundToken.Value       = tokens.Value.Value;
                        foundToken.Id          = tokens.Value.Id;
                        foundToken.IsKeyword   = tokens.Value.IsKeyword;
                        foundToken.SourceIndex = _Index;
                        foundToken.TokenString = tokens.Key;

                        _Index += tokens.Key.Length;
                        found   = true;

                        break;
                    }
                }

                if (found == false)
                {
                    // Look for some stuff.
                    // So it could be a space, control character that i have missed?
                    // Number, word, etc.
                    if (_Source[_Index] == ' ')
                    {
                        _Index++;
                    }
                    else // Skip over for now, however will change to read string.
                    {
                        foundToken             = new HVMToken();
                        foundToken.Id          = HVMTokenId.LiteralIdentifier;
                        foundToken.IsKeyword   = false;
                        foundToken.SourceIndex = _Index;
                        string literal = GetString();
                        foundToken.Value = literal;
                    }
                }
                else if (found == true) // Some checking and catching of invalid keyword tokens.
                {
                    // Keywords need to be checked that what the keyword thinks it is
                    // and what it actually is could be different things.
                    if (foundToken.IsKeyword == true)
                    {
                        // This makes you think it needs + 1 however source index is the first character
                        // For this token so adding the length will go to the last+1 character.
                        int peekAheadCharacter = foundToken.TokenString.Length + foundToken.SourceIndex;
                        if (peekAheadCharacter < _Source.Length)
                        {
                            char peekAhead = _Source[peekAheadCharacter];
                            if (char.IsLetterOrDigit(peekAhead) || peekAhead == '_')
                            {
                                _Index = foundToken.SourceIndex;
                                // Read this as a word or it could be a number
                                // Both are literals in this stage of the compiler.
                                foundToken             = new HVMToken();
                                foundToken.Id          = HVMTokenId.LiteralIdentifier;
                                foundToken.IsKeyword   = false;
                                foundToken.SourceIndex = _Index;
                                foundToken.Value       = GetString();

                                _Index = foundToken.SourceIndex + foundToken.Value.Length;
                            }
                        }
                    }
                }

                if (foundToken != null)
                {
                    Console.WriteLine(foundToken.Id + " " + foundToken.Value);
                    this._Tokens.Add(foundToken);
                }
            }

            return(_Tokens);
        }
Beispiel #7
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);
                }
            }
        }