public FunctionDefinitionNode(TypeReferenceNode returnType, string name, FunctionParameterNode[] parameters, BlockNode body, Token token, int tokenIndex) : base(token, tokenIndex)
 {
     Body = body;
     Name = name;
     Parameters = parameters;
     ReturnType = returnType;
 }
 public TypeReferenceNode(string name, TypeClassification classification, TypeModifiers modifiers, TypeReferenceNode inner, Token token, int tokenIndex) : base(token, tokenIndex)
 {
     Name = name;
     Classification = classification;
     Modifiers = modifiers;
     InnerType = inner;
 }
 public ILTypeReference ResolveTypeReference(TypeReferenceNode typeReferenceNode)
 {
     ILScope currentScope = CurrentScope;
     do
     {
         ILTypeReference? typeReference = TryResolveTypeReference(typeReferenceNode, currentScope);
         if (typeReference != null)
             return typeReference.Value;
     } while ((currentScope = currentScope.ParentScope) != null);
     throw new ParserException(string.Format("Unable to resolve type \"{0}\".", typeReferenceNode.Name), typeReferenceNode.TokenIndex, typeReferenceNode.Token);
 }
        public static TypeReferenceNode Parse(Token[] tokens, ref int i)
        {
            Token startToken = tokens[i];
            int startTokenIndex = i;

            TypeReferenceNode outer = null;
            TypeModifiers modifiers = ReadModifiers(tokens, ref i);
            if (Parser.CheckLiteral(tokens, i, TokenType.AlphaNum, "struct"))
            {
                i++; //Consume struct token
                string structName = null;
                if (Parser.Check(tokens, i, TokenType.AlphaNum) && !Keywords.IsKeyword(Parser.Peek(tokens, i).Literal))
                    structName = Parser.Expect(tokens, ref i, TokenType.AlphaNum).Literal;
                StructDefinitionNode embeddedStruct = null;
                if (Parser.Check(tokens, i, TokenType.LeftCurlyBrace))
                {
                    embeddedStruct = StructDefinitionNode.ParseBodyOnly(tokens, ref i, structName, true); //Todo: Disallow methods in structs in functions
                }
                if (outer != null)
                    throw new ParserException("Unexpected token in type.", i, tokens[i]);
                outer = new TypeReferenceNode(structName, TypeClassification.Struct, modifiers, startToken, startTokenIndex);
                outer.EmbeddedTypeDefinition = embeddedStruct;
            }
            else
            {
                string typeName = "";
                if (Parser.CheckLiteral(tokens, i, TokenType.AlphaNum, "unsigned"))
                {
                    typeName += tokens[i].Literal;
                    i++;
                }
                //Read Modifiers
                string typeNameMain = Parser.Expect(tokens, ref i, TokenType.AlphaNum).Literal;
                if (Keywords.IsNonTypeKeyword(typeNameMain))
                    throw new ParserException(string.Format("Unexpected keyword \"{0}\"", typeNameMain), i, tokens[i]);
                typeName += typeNameMain;
                if (outer != null)
                    throw new ParserException("Unexpected token in type.", i, tokens[i]);
                outer = new TypeReferenceNode(typeName, TypeClassification.Standard, modifiers, startToken, startTokenIndex);
            }

            while (Parser.Check(tokens, i, TokenType.Star) || IsModifier(tokens, i))
            {
                modifiers = ReadModifiers(tokens, ref i);
                Parser.Expect(tokens, ref i, TokenType.Star);
                outer = new TypeReferenceNode(null, TypeClassification.Pointer, modifiers, outer, startToken, startTokenIndex);
            }
            return outer;
        }
 private ILTypeReference? TryResolveTypeReference(TypeReferenceNode typeReferenceNode, ILScope scope)
 {
     //Todo: Process embedded types
     switch (typeReferenceNode.Classification)
     {
         case TypeClassification.Standard:
             if (Types.IsBaseType(typeReferenceNode.Name))
             {
                 BaseType baseType = Types.GetBaseTypeByName(typeReferenceNode.Name);
                 return new ILTypeReference(new ILBaseType(baseType), typeReferenceNode.Modifiers);
             }
             else if (scope.Typedefs.ContainsKey(typeReferenceNode.Name))
             {
                 ILTypeReference typedef = scope.Typedefs[typeReferenceNode.Name];
                 typedef.Modifiers |= typeReferenceNode.Modifiers;
                 return typedef;
             }
             else if (scope.EnumNames.Contains(typeReferenceNode.Name))
             {
                 return new ILTypeReference(new ILBaseType(Types.GetEnumBaseType()), typeReferenceNode.Modifiers);
             }
             else
             {
                 return null;
             }
         case TypeClassification.Struct:
             if (scope.Structs.ContainsKey(typeReferenceNode.Name))
                 return new ILTypeReference(scope.Structs[typeReferenceNode.Name], TypeModifiers.None);
             else
                 return null;
         case TypeClassification.Pointer:
             ILTypeReference? innerType = TryResolveTypeReference(typeReferenceNode.InnerType, scope);
             if (innerType == null)
                 return null;
             ILTypeReference returnType = new ILTypeReference(new ILPointerType(innerType.Value), typeReferenceNode.Modifiers);
             return returnType;
         default:
             throw new InternalCompilerException("Unexpected type classification.");
     }
 }
 public FunctionDeclarationNode(TypeReferenceNode returnType, string name, FunctionParameterNode[] parameters, Token token, int tokenIndex) : base(token, tokenIndex)
 {
     Name = name;
     Parameters = parameters;
     ReturnType = returnType;
 }
 public TypedefNode(TypeReferenceNode type, string name, Token token, int tokenIndex) : base(token, tokenIndex)
 {
     Type = type;
     Name = name;
 }
 public CastNode(SubExpressionNode expression, TypeReferenceNode type, Token token, int tokenIndex) : base(token, tokenIndex)
 {
     Expression = expression;
     Type = type;
 }
 public FunctionParameterNode(TypeReferenceNode type, string name, Token token, int tokenIndex) : base(token, tokenIndex)
 {
     Name = name;
     Type = type;
 }