Compare commits
	
		
			1 Commits 
		
	
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | f46630b0ab | 
							
								
								
									
										166
									
								
								.clang-format
								
								
								
								
							
							
						
						
									
										166
									
								
								.clang-format
								
								
								
								
							|  | @ -1,166 +0,0 @@ | ||||||
| --- |  | ||||||
| Language:        Cpp |  | ||||||
| # BasedOnStyle:  LLVM |  | ||||||
| AccessModifierOffset: -2 |  | ||||||
| AlignAfterOpenBracket: AlwaysBreak |  | ||||||
| AlignConsecutiveMacros: None |  | ||||||
| AlignConsecutiveAssignments: None |  | ||||||
| AlignConsecutiveBitFields: None |  | ||||||
| AlignConsecutiveDeclarations: None |  | ||||||
| AlignEscapedNewlines: Right |  | ||||||
| AlignOperands:   Align |  | ||||||
| AlignTrailingComments: true |  | ||||||
| AllowAllArgumentsOnNextLine: false |  | ||||||
| AllowAllConstructorInitializersOnNextLine: true |  | ||||||
| AllowAllParametersOfDeclarationOnNextLine: false |  | ||||||
| AllowShortEnumsOnASingleLine: true |  | ||||||
| AllowShortBlocksOnASingleLine: Never |  | ||||||
| AllowShortCaseLabelsOnASingleLine: false |  | ||||||
| AllowShortFunctionsOnASingleLine: All |  | ||||||
| AllowShortLambdasOnASingleLine: All |  | ||||||
| AllowShortIfStatementsOnASingleLine: Never |  | ||||||
| AllowShortLoopsOnASingleLine: false |  | ||||||
| AlwaysBreakAfterDefinitionReturnType: None |  | ||||||
| AlwaysBreakAfterReturnType: None |  | ||||||
| AlwaysBreakBeforeMultilineStrings: false |  | ||||||
| AlwaysBreakTemplateDeclarations: MultiLine |  | ||||||
| AttributeMacros: |  | ||||||
|   - __capability |  | ||||||
| BinPackArguments: false |  | ||||||
| BinPackParameters: false |  | ||||||
| BraceWrapping: |  | ||||||
|   AfterCaseLabel:  false |  | ||||||
|   AfterClass:      false |  | ||||||
|   AfterControlStatement: Never |  | ||||||
|   AfterEnum:       false |  | ||||||
|   AfterFunction:   false |  | ||||||
|   AfterNamespace:  false |  | ||||||
|   AfterObjCDeclaration: false |  | ||||||
|   AfterStruct:     false |  | ||||||
|   AfterUnion:      false |  | ||||||
|   AfterExternBlock: false |  | ||||||
|   BeforeCatch:     false |  | ||||||
|   BeforeElse:      false |  | ||||||
|   BeforeLambdaBody: false |  | ||||||
|   BeforeWhile:     false |  | ||||||
|   IndentBraces:    false |  | ||||||
|   SplitEmptyFunction: true |  | ||||||
|   SplitEmptyRecord: true |  | ||||||
|   SplitEmptyNamespace: true |  | ||||||
| BreakBeforeBinaryOperators: None |  | ||||||
| BreakBeforeConceptDeclarations: true |  | ||||||
| BreakBeforeBraces: Allman |  | ||||||
| BreakBeforeInheritanceComma: false |  | ||||||
| BreakInheritanceList: BeforeColon |  | ||||||
| BreakBeforeTernaryOperators: true |  | ||||||
| BreakConstructorInitializersBeforeComma: false |  | ||||||
| BreakConstructorInitializers: BeforeColon |  | ||||||
| BreakAfterJavaFieldAnnotations: false |  | ||||||
| BreakStringLiterals: true |  | ||||||
| ColumnLimit:     80 |  | ||||||
| CommentPragmas:  '^ IWYU pragma:' |  | ||||||
| CompactNamespaces: false |  | ||||||
| ConstructorInitializerAllOnOneLineOrOnePerLine: false |  | ||||||
| ConstructorInitializerIndentWidth: 4 |  | ||||||
| ContinuationIndentWidth: 4 |  | ||||||
| Cpp11BracedListStyle: true |  | ||||||
| DeriveLineEnding: true |  | ||||||
| DerivePointerAlignment: false |  | ||||||
| DisableFormat:   false |  | ||||||
| EmptyLineBeforeAccessModifier: LogicalBlock |  | ||||||
| ExperimentalAutoDetectBinPacking: false |  | ||||||
| FixNamespaceComments: true |  | ||||||
| ForEachMacros: |  | ||||||
|   - foreach |  | ||||||
|   - Q_FOREACH |  | ||||||
|   - BOOST_FOREACH |  | ||||||
| StatementAttributeLikeMacros: |  | ||||||
|   - Q_EMIT |  | ||||||
| IncludeBlocks:   Preserve |  | ||||||
| IncludeCategories: |  | ||||||
|   - Regex:           '^"(llvm|llvm-c|clang|clang-c)/' |  | ||||||
|     Priority:        2 |  | ||||||
|     SortPriority:    0 |  | ||||||
|     CaseSensitive:   false |  | ||||||
|   - Regex:           '^(<|"(gtest|gmock|isl|json)/)' |  | ||||||
|     Priority:        3 |  | ||||||
|     SortPriority:    0 |  | ||||||
|     CaseSensitive:   false |  | ||||||
|   - Regex:           '.*' |  | ||||||
|     Priority:        1 |  | ||||||
|     SortPriority:    0 |  | ||||||
|     CaseSensitive:   false |  | ||||||
| IncludeIsMainRegex: '(Test)?$' |  | ||||||
| IncludeIsMainSourceRegex: '' |  | ||||||
| IndentCaseLabels: false |  | ||||||
| IndentCaseBlocks: false |  | ||||||
| IndentGotoLabels: true |  | ||||||
| IndentPPDirectives: None |  | ||||||
| IndentExternBlock: AfterExternBlock |  | ||||||
| IndentRequires:  false |  | ||||||
| IndentWidth:     4 |  | ||||||
| IndentWrappedFunctionNames: false |  | ||||||
| InsertTrailingCommas: None |  | ||||||
| JavaScriptQuotes: Leave |  | ||||||
| JavaScriptWrapImports: true |  | ||||||
| KeepEmptyLinesAtTheStartOfBlocks: true |  | ||||||
| MacroBlockBegin: '' |  | ||||||
| MacroBlockEnd:   '' |  | ||||||
| MaxEmptyLinesToKeep: 1 |  | ||||||
| NamespaceIndentation: None |  | ||||||
| ObjCBinPackProtocolList: Auto |  | ||||||
| ObjCBlockIndentWidth: 4 |  | ||||||
| ObjCBreakBeforeNestedBlockParam: true |  | ||||||
| ObjCSpaceAfterProperty: false |  | ||||||
| ObjCSpaceBeforeProtocolList: true |  | ||||||
| PenaltyBreakAssignment: 2 |  | ||||||
| PenaltyBreakBeforeFirstCallParameter: 19 |  | ||||||
| PenaltyBreakComment: 300 |  | ||||||
| PenaltyBreakFirstLessLess: 120 |  | ||||||
| PenaltyBreakString: 1000 |  | ||||||
| PenaltyBreakTemplateDeclaration: 10 |  | ||||||
| PenaltyExcessCharacter: 1000000 |  | ||||||
| PenaltyReturnTypeOnItsOwnLine: 1000000 |  | ||||||
| PenaltyIndentedWhitespace: 0 |  | ||||||
| PointerAlignment: Right |  | ||||||
| ReflowComments:  true |  | ||||||
| SortIncludes:    true |  | ||||||
| SortJavaStaticImport: Before |  | ||||||
| SortUsingDeclarations: true |  | ||||||
| SpaceAfterCStyleCast: false |  | ||||||
| SpaceAfterLogicalNot: false |  | ||||||
| SpaceAfterTemplateKeyword: true |  | ||||||
| SpaceBeforeAssignmentOperators: true |  | ||||||
| SpaceBeforeCaseColon: false |  | ||||||
| SpaceBeforeCpp11BracedList: false |  | ||||||
| SpaceBeforeCtorInitializerColon: true |  | ||||||
| SpaceBeforeInheritanceColon: true |  | ||||||
| SpaceBeforeParens: ControlStatements |  | ||||||
| SpaceAroundPointerQualifiers: Default |  | ||||||
| SpaceBeforeRangeBasedForLoopColon: true |  | ||||||
| SpaceInEmptyBlock: false |  | ||||||
| SpaceInEmptyParentheses: false |  | ||||||
| SpacesBeforeTrailingComments: 1 |  | ||||||
| SpacesInAngles:  false |  | ||||||
| SpacesInConditionalStatement: false |  | ||||||
| SpacesInContainerLiterals: true |  | ||||||
| SpacesInCStyleCastParentheses: false |  | ||||||
| SpacesInParentheses: false |  | ||||||
| SpacesInSquareBrackets: false |  | ||||||
| SpaceBeforeSquareBrackets: false |  | ||||||
| BitFieldColonSpacing: Both |  | ||||||
| Standard:        Latest |  | ||||||
| StatementMacros: |  | ||||||
|   - Q_UNUSED |  | ||||||
|   - QT_REQUIRE_VERSION |  | ||||||
| TabWidth:        8 |  | ||||||
| UseCRLF:         false |  | ||||||
| UseTab:          Never |  | ||||||
| WhitespaceSensitiveMacros: |  | ||||||
|   - STRINGIZE |  | ||||||
|   - PP_STRINGIZE |  | ||||||
|   - BOOST_PP_STRINGIZE |  | ||||||
|   - NS_SWIFT_NAME |  | ||||||
|   - CF_SWIFT_NAME |  | ||||||
| ... |  | ||||||
| 
 |  | ||||||
|  | @ -23,7 +23,7 @@ find_package(LLVM) | ||||||
| 
 | 
 | ||||||
| include_directories(${CMAKE_SOURCE_DIR}) | include_directories(${CMAKE_SOURCE_DIR}) | ||||||
| 
 | 
 | ||||||
| BISON_TARGET(Parser generators/wraith.y ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c COMPILE_FLAGS "-d -v -t") | BISON_TARGET(Parser generators/wraith.y ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c COMPILE_FLAGS "-d -v -t -Wcounterexamples") | ||||||
| FLEX_TARGET(Scanner generators/wraith.lex ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c) | FLEX_TARGET(Scanner generators/wraith.lex ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c) | ||||||
| 
 | 
 | ||||||
| ADD_FLEX_BISON_DEPENDENCY(Scanner Parser) | ADD_FLEX_BISON_DEPENDENCY(Scanner Parser) | ||||||
|  | @ -42,13 +42,9 @@ add_executable( | ||||||
| 	src/ast.h | 	src/ast.h | ||||||
| 	src/codegen.h | 	src/codegen.h | ||||||
| 	src/parser.h | 	src/parser.h | ||||||
| 	src/validation.h |  | ||||||
| 	src/util.h |  | ||||||
|     src/ast.c |     src/ast.c | ||||||
| 	src/codegen.c | 	src/codegen.c | ||||||
| 	src/parser.c | 	src/parser.c | ||||||
| 	src/validation.c |  | ||||||
| 	src/util.c |  | ||||||
| 	src/main.c | 	src/main.c | ||||||
| 	# Generated code | 	# Generated code | ||||||
|     ${BISON_Parser_OUTPUTS} |     ${BISON_Parser_OUTPUTS} | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								access.w
								
								
								
								
							
							
						
						
									
										13
									
								
								access.w
								
								
								
								
							|  | @ -1,13 +0,0 @@ | ||||||
| struct G { |  | ||||||
|     Foo(t: bool): bool { |  | ||||||
|         return t; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct Program { |  | ||||||
|     static main(): int { |  | ||||||
|         g: G = alloc G; |  | ||||||
|         g.Foo(true); |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | @ -1,6 +0,0 @@ | ||||||
| struct Program {  |  | ||||||
|     // This triggers a parse error |  | ||||||
|     static Main(): int { |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										14
									
								
								example.w
								
								
								
								
							
							
						
						
									
										14
									
								
								example.w
								
								
								
								
							|  | @ -1,6 +1,16 @@ | ||||||
|  | interface Increments | ||||||
|  | { | ||||||
|  |     Increment(): void; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| struct YourStruct | struct YourStruct | ||||||
| { | { | ||||||
|     yourInt: int; |     yourInt: int; | ||||||
|  | 
 | ||||||
|  |     IncrementOther<T: Increments>(other: T): void | ||||||
|  |     { | ||||||
|  |         other.Increment(); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct MyStruct | struct MyStruct | ||||||
|  | @ -54,8 +64,6 @@ struct Program | ||||||
|             myStruct.myInt = 4; |             myStruct.myInt = 4; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Console.PrintLine("%i", myStruct.myInt); |         return myStruct.myInt; | ||||||
| 
 |  | ||||||
|         return 0; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -12,8 +12,8 @@ | ||||||
| "double"                    return DOUBLE; | "double"                    return DOUBLE; | ||||||
| "string"                    return STRING; | "string"                    return STRING; | ||||||
| "bool"                      return BOOL; | "bool"                      return BOOL; | ||||||
| "MemoryAddress"             return MEMORYADDRESS; |  | ||||||
| "struct"                    return STRUCT; | "struct"                    return STRUCT; | ||||||
|  | "interface"                 return INTERFACE; | ||||||
| "return"                    return RETURN; | "return"                    return RETURN; | ||||||
| "static"                    return STATIC; | "static"                    return STATIC; | ||||||
| "Reference"                 return REFERENCE; | "Reference"                 return REFERENCE; | ||||||
|  | @ -41,7 +41,6 @@ | ||||||
| ";"                         return SEMICOLON; | ";"                         return SEMICOLON; | ||||||
| ":"                         return COLON; | ":"                         return COLON; | ||||||
| "?"                         return QUESTION; | "?"                         return QUESTION; | ||||||
| "@"                         return AT; |  | ||||||
| "("                         return LEFT_PAREN; | "("                         return LEFT_PAREN; | ||||||
| ")"                         return RIGHT_PAREN; | ")"                         return RIGHT_PAREN; | ||||||
| "["                         return LEFT_BRACKET; | "["                         return LEFT_BRACKET; | ||||||
|  |  | ||||||
|  | @ -25,8 +25,8 @@ extern FILE *yyin; | ||||||
| %token DOUBLE | %token DOUBLE | ||||||
| %token STRING | %token STRING | ||||||
| %token BOOL | %token BOOL | ||||||
| %token MEMORYADDRESS |  | ||||||
| %token STRUCT | %token STRUCT | ||||||
|  | %token INTERFACE | ||||||
| %token RETURN | %token RETURN | ||||||
| %token STATIC | %token STATIC | ||||||
| %token REFERENCE | %token REFERENCE | ||||||
|  | @ -55,7 +55,6 @@ extern FILE *yyin; | ||||||
| %token SEMICOLON | %token SEMICOLON | ||||||
| %token COLON | %token COLON | ||||||
| %token QUESTION | %token QUESTION | ||||||
| %token AT |  | ||||||
| %token LEFT_PAREN | %token LEFT_PAREN | ||||||
| %token RIGHT_PAREN | %token RIGHT_PAREN | ||||||
| %token LEFT_BRACE | %token LEFT_BRACE | ||||||
|  | @ -109,17 +108,9 @@ BaseType                : VOID | ||||||
|                         { |                         { | ||||||
|                             $$ = MakePrimitiveTypeNode(Bool); |                             $$ = MakePrimitiveTypeNode(Bool); | ||||||
|                         } |                         } | ||||||
|                         | MEMORYADDRESS |  | ||||||
|                         { |  | ||||||
|                             $$ = MakePrimitiveTypeNode(MemoryAddress); |  | ||||||
|                         } |  | ||||||
|                         | Identifier GenericArgumentClauseNonEmpty |  | ||||||
|                         { |  | ||||||
|                             $$ = MakeConcreteGenericTypeNode($1, $2); |  | ||||||
|                         } |  | ||||||
|                         | Identifier |                         | Identifier | ||||||
|                         { |                         { | ||||||
|                             $$ = MakeCustomTypeNode($1); |                             $$ = MakeCustomTypeNode(yytext); | ||||||
|                         } |                         } | ||||||
|                         | REFERENCE LESS_THAN Type GREATER_THAN |                         | REFERENCE LESS_THAN Type GREATER_THAN | ||||||
|                         { |                         { | ||||||
|  | @ -151,40 +142,11 @@ AccessExpression        : Identifier POINT AccessExpression | ||||||
|                             $$ = $1; |                             $$ = $1; | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| SystemCallExpression    : AT Identifier |  | ||||||
|                         { |  | ||||||
|                             $$ = $2; |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
| Number                  : NUMBER | Number                  : NUMBER | ||||||
|                         { |                         { | ||||||
|                             $$ = MakeNumberNode(yytext); |                             $$ = MakeNumberNode(yytext); | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| FieldInit               : Identifier COLON Expression |  | ||||||
|                         { |  | ||||||
|                             $$ = MakeFieldInitNode($1, $3); |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
| StructInitFields        : FieldInit |  | ||||||
|                         { |  | ||||||
|                             $$ = StartStructInitFieldsNode($1); |  | ||||||
|                         } |  | ||||||
|                         | StructInitFields COMMA FieldInit |  | ||||||
|                         { |  | ||||||
|                             $$ = AddFieldInitNode($1, $3); |  | ||||||
|                         } |  | ||||||
|                         | |  | ||||||
|                         { |  | ||||||
|                             $$ = MakeEmptyFieldInitNode(); |  | ||||||
|                         } |  | ||||||
|                         ; |  | ||||||
| 
 |  | ||||||
| StructInitExpression    : Type LEFT_BRACE StructInitFields RIGHT_BRACE |  | ||||||
|                         { |  | ||||||
|                             $$ = MakeStructInitExpressionNode($1, $3); |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
| PrimaryExpression       : Number | PrimaryExpression       : Number | ||||||
|                         | STRING_LITERAL |                         | STRING_LITERAL | ||||||
|                         { |                         { | ||||||
|  | @ -196,7 +158,6 @@ PrimaryExpression       : Number | ||||||
|                         } |                         } | ||||||
|                         | FunctionCallExpression |                         | FunctionCallExpression | ||||||
|                         | AccessExpression |                         | AccessExpression | ||||||
|                         | StructInitExpression |  | ||||||
|                         ; |                         ; | ||||||
| 
 | 
 | ||||||
| UnaryExpression         : BANG Expression | UnaryExpression         : BANG Expression | ||||||
|  | @ -270,13 +231,9 @@ ReturnStatement         : RETURN Expression | ||||||
|                             $$ = MakeReturnVoidStatementNode(); |                             $$ = MakeReturnVoidStatementNode(); | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| FunctionCallExpression  : AccessExpression GenericArgumentClause LEFT_PAREN Arguments RIGHT_PAREN | FunctionCallExpression  : AccessExpression LEFT_PAREN Arguments RIGHT_PAREN | ||||||
|                         { |                         { | ||||||
|                             $$ = MakeFunctionCallExpressionNode($1, $4, $2); |                             $$ = MakeFunctionCallExpressionNode($1, $3); | ||||||
|                         } |  | ||||||
|                         | SystemCallExpression GenericArgumentClause LEFT_PAREN Arguments RIGHT_PAREN |  | ||||||
|                         { |  | ||||||
|                             $$ = MakeSystemCallExpressionNode($1, $4, $2); |  | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| PartialStatement        : FunctionCallExpression | PartialStatement        : FunctionCallExpression | ||||||
|  | @ -319,11 +276,11 @@ Statements              : Statement | ||||||
|                             $$ = AddStatement($1, $2); |                             $$ = AddStatement($1, $2); | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| Arguments               : Expression | Arguments               : PrimaryExpression | ||||||
|                         { |                         { | ||||||
|                             $$ = StartFunctionArgumentSequenceNode($1); |                             $$ = StartFunctionArgumentSequenceNode($1); | ||||||
|                         } |                         } | ||||||
|                         | Arguments COMMA Expression |                         | Arguments COMMA PrimaryExpression | ||||||
|                         { |                         { | ||||||
|                             $$ = AddFunctionArgumentNode($1, $3); |                             $$ = AddFunctionArgumentNode($1, $3); | ||||||
|                         } |                         } | ||||||
|  | @ -351,63 +308,40 @@ Body                    : LEFT_BRACE Statements RIGHT_BRACE | ||||||
|                             $$ = $2; |                             $$ = $2; | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| GenericDeclaration      : Identifier | GenericConstraint       : Identifier COLON Identifier | ||||||
|                         { |                         { | ||||||
|                             $$ = MakeGenericDeclarationNode($1, NULL); |                             $$ = MakeGenericConstraintNode($1, $3); | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| GenericDeclarations     : GenericDeclaration | GenericConstraints      : GenericConstraint | ||||||
|                         { |                         { | ||||||
|                             $$ = StartGenericDeclarationsNode($1); |                             $$ = StartGenericConstraintsNode($1); | ||||||
|                         } |                         } | ||||||
|                         | GenericDeclarations COMMA GenericDeclaration |                         | GenericConstraints COMMA GenericConstraint | ||||||
|                         { |                         { | ||||||
|                             $$ = AddGenericDeclaration($1, $3); |                             $$ = AddGenericConstraint($1, $3); | ||||||
|                         } |                         } | ||||||
|  |                         ; | ||||||
| 
 | 
 | ||||||
| GenericDeclarationClause    : LESS_THAN GenericDeclarations GREATER_THAN | GenericConstraintClause : LESS_THAN GenericConstraints GREATER_THAN | ||||||
|                             { |  | ||||||
|                                 $$ = $2; |  | ||||||
|                             } |  | ||||||
|                             | |  | ||||||
|                             { |  | ||||||
|                                 $$ = MakeEmptyGenericDeclarationsNode(); |  | ||||||
|                             } |  | ||||||
| 
 |  | ||||||
| GenericArgument         : Type |  | ||||||
|                         { |                         { | ||||||
|                             $$ = MakeGenericArgumentNode($1); |                             $$ = $2; | ||||||
|                         } |                         } | ||||||
| 
 |  | ||||||
| GenericArguments        : GenericArgument |  | ||||||
|                         { |  | ||||||
|                             $$ = StartGenericArgumentsNode($1); |  | ||||||
|                         } |  | ||||||
|                         | GenericArguments COMMA GenericArgument |  | ||||||
|                         { |  | ||||||
|                             $$ = AddGenericArgument($1, $3); |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
| GenericArgumentClauseNonEmpty   : LESS_THAN GenericArguments GREATER_THAN |  | ||||||
|                                 { |  | ||||||
|                                     $$ = $2; |  | ||||||
|                                 } |  | ||||||
|                                 ; |  | ||||||
| 
 |  | ||||||
| GenericArgumentClause   : GenericArgumentClauseNonEmpty |  | ||||||
|                         | |                         | | ||||||
|                         { |                         { | ||||||
|                             $$ = MakeEmptyGenericArgumentsNode(); |                             $$ = MakeEmptyGenericConstraintsNode(); | ||||||
|                         } |                         } | ||||||
|  |                         ; | ||||||
| 
 | 
 | ||||||
| FunctionSignature       : Identifier GenericDeclarationClause LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type | /* FIXME: modifiers should be recursive */ | ||||||
|  | FunctionSignature       : Identifier GenericConstraintClause LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type | ||||||
|                         { |                         { | ||||||
|                             $$ = MakeFunctionSignatureNode($1, $7, $4, MakeFunctionModifiersNode(NULL, 0), $2); |                             $$ = MakeFunctionSignatureNode($1, $7, $4, MakeFunctionModifiersNode(NULL, 0), $2); | ||||||
|                         } |                         } | ||||||
|                         | STATIC Identifier GenericDeclarationClause LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type |                         | STATIC Identifier LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type | ||||||
|                         { |                         { | ||||||
|                             Node *modifier = MakeStaticNode(); |                             Node *modifier = MakeStaticNode(); | ||||||
|                             $$ = MakeFunctionSignatureNode($2, $8, $5, MakeFunctionModifiersNode(&modifier, 1), $3); |                             $$ = MakeFunctionSignatureNode($2, $7, $4, MakeFunctionModifiersNode(&modifier, 1), MakeEmptyGenericConstraintsNode()); | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| FunctionDeclaration     : FunctionSignature Body | FunctionDeclaration     : FunctionSignature Body | ||||||
|  | @ -415,11 +349,29 @@ FunctionDeclaration     : FunctionSignature Body | ||||||
|                             $$ = MakeFunctionDeclarationNode($1, $2); |                             $$ = MakeFunctionDeclarationNode($1, $2); | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| StructDeclaration       : STRUCT Identifier GenericDeclarationClause LEFT_BRACE Declarations RIGHT_BRACE | StructDeclaration       : STRUCT Identifier LEFT_BRACE Declarations RIGHT_BRACE | ||||||
|                         { |                         { | ||||||
|                             $$ = MakeStructDeclarationNode($2, $5, $3); |                             $$ = MakeStructDeclarationNode($2, $4); | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
|  | InterfaceDeclaration    : INTERFACE Identifier LEFT_BRACE InterfaceChildren RIGHT_BRACE | ||||||
|  |                         { | ||||||
|  |                             $$ = MakeInterfaceDeclarationNode($2, $4); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  | InterfaceChild          : FunctionSignature SEMICOLON | ||||||
|  |                         ; | ||||||
|  | 
 | ||||||
|  | InterfaceChildren       : InterfaceChild | ||||||
|  |                         { | ||||||
|  |                             $$ = StartDeclarationSequenceNode($1); | ||||||
|  |                         } | ||||||
|  |                         | InterfaceChildren InterfaceChild | ||||||
|  |                         { | ||||||
|  |                             $$ = AddDeclarationNode($1, $2); | ||||||
|  |                         } | ||||||
|  |                         ; | ||||||
|  | 
 | ||||||
| Declaration             : FunctionDeclaration | Declaration             : FunctionDeclaration | ||||||
|                         | VariableDeclaration SEMICOLON |                         | VariableDeclaration SEMICOLON | ||||||
|                         ; |                         ; | ||||||
|  | @ -433,7 +385,9 @@ Declarations            : Declaration | ||||||
|                             $$ = AddDeclarationNode($1, $2); |                             $$ = AddDeclarationNode($1, $2); | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
| TopLevelDeclaration     : StructDeclaration; | TopLevelDeclaration     : StructDeclaration | ||||||
|  |                         | InterfaceDeclaration | ||||||
|  |                         ; | ||||||
| 
 | 
 | ||||||
| TopLevelDeclarations    : TopLevelDeclaration | TopLevelDeclarations    : TopLevelDeclaration | ||||||
|                         { |                         { | ||||||
|  |  | ||||||
							
								
								
									
										59
									
								
								generic.w
								
								
								
								
							
							
						
						
									
										59
									
								
								generic.w
								
								
								
								
							|  | @ -1,59 +0,0 @@ | ||||||
| struct Foo { |  | ||||||
|     static Func2<U>(u: U) : U { |  | ||||||
|         return u; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     static Func<T>(t: T): T { |  | ||||||
|         foo: T = t; |  | ||||||
|         return Foo.Func2(foo); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct MemoryBlock<T> |  | ||||||
| { |  | ||||||
| 	start: MemoryAddress; |  | ||||||
| 	capacity: uint; |  | ||||||
| 
 |  | ||||||
| 	AddressOf(index: uint): MemoryAddress |  | ||||||
|     { |  | ||||||
|         return start + (index * @sizeof<T>()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     Get(index: uint): T |  | ||||||
|     { |  | ||||||
|         return @dereference<T>(AddressOf(index)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     Set(index: uint, value: T): void |  | ||||||
|     { |  | ||||||
|         @memcpy(AddressOf(index), @addr(value), @sizeof<T>()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     Free(): void |  | ||||||
|     { |  | ||||||
|         @free(start); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct Program { |  | ||||||
|     static Main(): int { |  | ||||||
|         x: int = 4; |  | ||||||
|         y: int = Foo.Func(x); |  | ||||||
|         block: MemoryBlock<int> = MemoryBlock<int> |  | ||||||
|         { |  | ||||||
|             capacity: y, |  | ||||||
|             start: @malloc(y * @sizeof<int>()) |  | ||||||
|         }; |  | ||||||
|         block.Set(0, 5); |  | ||||||
|         block.Set(1, 3); |  | ||||||
|         block.Set(2, 9); |  | ||||||
|         block.Set(3, 100); |  | ||||||
|         Console.PrintLine("%p", block.start); |  | ||||||
|         Console.PrintLine("%i", block.Get(0)); |  | ||||||
|         Console.PrintLine("%i", block.Get(1)); |  | ||||||
|         Console.PrintLine("%i", block.Get(2)); |  | ||||||
|         Console.PrintLine("%i", block.Get(3)); |  | ||||||
|         block.Free(); |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										44
									
								
								iftest.w
								
								
								
								
							
							
						
						
									
										44
									
								
								iftest.w
								
								
								
								
							|  | @ -1,44 +0,0 @@ | ||||||
| struct MyStruct { |  | ||||||
|     static MyFunc(): int { |  | ||||||
|         myStructInt: int = 595959959; |  | ||||||
|         return myStructInt; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct Program { |  | ||||||
|     static Foo(): int { |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     static Main(): int { |  | ||||||
|         myInt: int = 54; |  | ||||||
|         if (myInt < 0) { |  | ||||||
|             signTag: int = 0 - 1; |  | ||||||
|         } else if (myInt == 0) { |  | ||||||
|             signTag: int = 0; |  | ||||||
|         } else { |  | ||||||
|             signTag: int = 1; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         myBool: bool; |  | ||||||
|         if (myBool) { |  | ||||||
|             if (myBool) { |  | ||||||
|                 if (myBool) { |  | ||||||
|                     if (myBool) { |  | ||||||
|                         if (myBool) { |  | ||||||
|                             lol: int = 69; |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         someInt: int = 9585858; |  | ||||||
| 
 |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     static Bar(): int { |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										15
									
								
								ordering.w
								
								
								
								
							
							
						
						
									
										15
									
								
								ordering.w
								
								
								
								
							|  | @ -1,15 +0,0 @@ | ||||||
| struct Foo { |  | ||||||
|     static Func(): void { |  | ||||||
|         Func2(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     static Func2(): void { |  | ||||||
|         Func(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct Program { |  | ||||||
|     static main(): int { |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										11
									
								
								reftest.w
								
								
								
								
							
							
						
						
									
										11
									
								
								reftest.w
								
								
								
								
							|  | @ -1,11 +0,0 @@ | ||||||
| struct MyStruct { |  | ||||||
|     foo: int; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct Program { |  | ||||||
|     static Main(): int { |  | ||||||
|         myStruct: Reference<MyStruct>; |  | ||||||
|         myStruct = alloc MyStruct; |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										520
									
								
								src/ast.h
								
								
								
								
							
							
						
						
									
										520
									
								
								src/ast.h
								
								
								
								
							|  | @ -3,15 +3,6 @@ | ||||||
| 
 | 
 | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
| /* -Wpedantic nameless union/struct silencing */ |  | ||||||
| #ifndef WRAITHNAMELESS |  | ||||||
| #ifdef __GNUC__ |  | ||||||
| #define WRAITHNAMELESS __extension__ |  | ||||||
| #else |  | ||||||
| #define WRAITHNAMELESS |  | ||||||
| #endif /* __GNUC__ */ |  | ||||||
| #endif /* WRAITHNAMELESS */ |  | ||||||
| 
 |  | ||||||
| typedef enum | typedef enum | ||||||
| { | { | ||||||
|     AccessExpression, |     AccessExpression, | ||||||
|  | @ -19,11 +10,10 @@ typedef enum | ||||||
|     Assignment, |     Assignment, | ||||||
|     BinaryExpression, |     BinaryExpression, | ||||||
|     Comment, |     Comment, | ||||||
|     ConcreteGenericTypeNode, |  | ||||||
|     CustomTypeNode, |     CustomTypeNode, | ||||||
|     Declaration, |     Declaration, | ||||||
|     DeclarationSequence, |     DeclarationSequence, | ||||||
|     FieldInit, |     Expression, | ||||||
|     ForLoop, |     ForLoop, | ||||||
|     FunctionArgumentSequence, |     FunctionArgumentSequence, | ||||||
|     FunctionCallExpression, |     FunctionCallExpression, | ||||||
|  | @ -31,14 +21,12 @@ typedef enum | ||||||
|     FunctionModifiers, |     FunctionModifiers, | ||||||
|     FunctionSignature, |     FunctionSignature, | ||||||
|     FunctionSignatureArguments, |     FunctionSignatureArguments, | ||||||
|     GenericArgument, |     GenericConstraint, | ||||||
|     GenericArguments, |     GenericConstraints, | ||||||
|     GenericDeclaration, |  | ||||||
|     GenericDeclarations, |  | ||||||
|     GenericTypeNode, |  | ||||||
|     Identifier, |     Identifier, | ||||||
|     IfStatement, |     IfStatement, | ||||||
|     IfElseStatement, |     IfElseStatement, | ||||||
|  |     InterfaceDeclaration, | ||||||
|     Number, |     Number, | ||||||
|     PrimitiveTypeNode, |     PrimitiveTypeNode, | ||||||
|     ReferenceTypeNode, |     ReferenceTypeNode, | ||||||
|  | @ -48,9 +36,6 @@ typedef enum | ||||||
|     StaticModifier, |     StaticModifier, | ||||||
|     StringLiteral, |     StringLiteral, | ||||||
|     StructDeclaration, |     StructDeclaration, | ||||||
|     StructInit, |  | ||||||
|     StructInitFields, |  | ||||||
|     SystemCall, |  | ||||||
|     Type, |     Type, | ||||||
|     UnaryExpression |     UnaryExpression | ||||||
| } SyntaxKind; | } SyntaxKind; | ||||||
|  | @ -80,8 +65,7 @@ typedef enum | ||||||
|     UInt, |     UInt, | ||||||
|     Float, |     Float, | ||||||
|     Double, |     Double, | ||||||
|     String, |     String | ||||||
|     MemoryAddress |  | ||||||
| } PrimitiveType; | } PrimitiveType; | ||||||
| 
 | 
 | ||||||
| typedef union | typedef union | ||||||
|  | @ -90,378 +74,160 @@ typedef union | ||||||
|     BinaryOperator binaryOperator; |     BinaryOperator binaryOperator; | ||||||
| } Operator; | } Operator; | ||||||
| 
 | 
 | ||||||
| typedef struct TypeTag TypeTag; | typedef struct Node | ||||||
| 
 |  | ||||||
| typedef struct ConcreteGenericTypeTag |  | ||||||
| { | { | ||||||
|     char *name; |     SyntaxKind syntaxKind; | ||||||
|     TypeTag **genericArguments; |     struct Node **children; | ||||||
|     uint32_t genericArgumentCount; |     uint32_t childCount; | ||||||
| } ConcreteGenericTypeTag; |  | ||||||
| 
 |  | ||||||
| struct TypeTag |  | ||||||
| { |  | ||||||
|     enum Type |  | ||||||
|     { |  | ||||||
|         Unknown, |  | ||||||
|         Primitive, |  | ||||||
|         Reference, |  | ||||||
|         Custom, |  | ||||||
|         Generic, |  | ||||||
|         ConcreteGeneric |  | ||||||
|     } type; |  | ||||||
|     union |     union | ||||||
|     { |     { | ||||||
|         /* Valid when type = Primitive. */ |         UnaryOperator unaryOperator; | ||||||
|         PrimitiveType primitiveType; |         BinaryOperator binaryOperator; | ||||||
|         /* Valid when type = Reference. */ |     } operator; | ||||||
|         struct TypeTag *referenceType; |     union | ||||||
|         /* Valid when type = Custom. */ |  | ||||||
|         char *customType; |  | ||||||
|         /* Valid when type = Generic. */ |  | ||||||
|         char *genericType; |  | ||||||
|         /* Valid when type = ConcreteGeneric */ |  | ||||||
|         ConcreteGenericTypeTag concreteGenericType; |  | ||||||
|     } value; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| typedef struct Node Node; |  | ||||||
| 
 |  | ||||||
| struct Node |  | ||||||
| { |  | ||||||
|     Node *parent; |  | ||||||
|     SyntaxKind syntaxKind; |  | ||||||
|     WRAITHNAMELESS union |  | ||||||
|     { |     { | ||||||
|         struct |         char *string; | ||||||
|         { |         uint64_t number; | ||||||
|             Node *accessee; |     } value; | ||||||
|             Node *accessor; |     PrimitiveType primitiveType; | ||||||
|         } accessExpression; | } Node; | ||||||
| 
 | 
 | ||||||
|         struct | char* strdup (const char* s); | ||||||
|         { | const char* SyntaxKindString(SyntaxKind syntaxKind); | ||||||
|             Node *type; |  | ||||||
|         } allocExpression; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *left; |  | ||||||
|             Node *right; |  | ||||||
|         } assignmentStatement; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *left; |  | ||||||
|             Node *right; |  | ||||||
|             BinaryOperator operator; |  | ||||||
|         } binaryExpression; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
| 
 |  | ||||||
|         } comment; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             char *name; |  | ||||||
|             Node *genericArguments; |  | ||||||
|         } concreteGenericType; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             char *name; |  | ||||||
|         } customType; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *type; |  | ||||||
|             Node *identifier; |  | ||||||
|         } declaration; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node **sequence; |  | ||||||
|             uint32_t count; |  | ||||||
|         } declarationSequence; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *identifier; |  | ||||||
|             Node *expression; |  | ||||||
|         } fieldInit; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *declaration; |  | ||||||
|             Node *startNumber; |  | ||||||
|             Node *endNumber; |  | ||||||
|             Node *statementSequence; |  | ||||||
|         } forLoop; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node **sequence; |  | ||||||
|             uint32_t count; |  | ||||||
|         } functionArgumentSequence; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *identifier; /* FIXME: need better name */ |  | ||||||
|             Node *argumentSequence; |  | ||||||
|             Node *genericArguments; |  | ||||||
|         } functionCallExpression; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *functionSignature; |  | ||||||
|             Node *functionBody; |  | ||||||
|         } functionDeclaration; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node **sequence; |  | ||||||
|             uint32_t count; |  | ||||||
|         } functionModifiers; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *identifier; |  | ||||||
|             Node *type; |  | ||||||
|             Node *arguments; |  | ||||||
|             Node *modifiers; |  | ||||||
|             Node *genericDeclarations; |  | ||||||
|         } functionSignature; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node **sequence; |  | ||||||
|             uint32_t count; |  | ||||||
|         } functionSignatureArguments; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *type; |  | ||||||
|         } genericArgument; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node **arguments; |  | ||||||
|             uint32_t count; |  | ||||||
|         } genericArguments; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *identifier; |  | ||||||
|             Node *constraint; |  | ||||||
|         } genericDeclaration; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node **declarations; |  | ||||||
|             uint32_t count; |  | ||||||
|         } genericDeclarations; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             char *name; |  | ||||||
|         } genericType; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             char *name; |  | ||||||
|         } identifier; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *expression; |  | ||||||
|             Node *statementSequence; |  | ||||||
|         } ifStatement; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *ifStatement; |  | ||||||
|             Node *elseStatement; |  | ||||||
|         } ifElseStatement; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             uint64_t value; |  | ||||||
|         } number; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             PrimitiveType type; |  | ||||||
|         } primitiveType; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *type; |  | ||||||
|         } referenceType; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *expression; |  | ||||||
|         } returnStatement; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
| 
 |  | ||||||
|         } returnVoidStatement; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node **sequence; |  | ||||||
|             uint32_t count; |  | ||||||
|         } statementSequence; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
| 
 |  | ||||||
|         } staticModifier; /* FIXME: modifiers should just be an enum */ |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             char *string; |  | ||||||
|         } stringLiteral; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *identifier; |  | ||||||
|             Node *declarationSequence; |  | ||||||
|             Node *genericDeclarations; |  | ||||||
|         } structDeclaration; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *type; |  | ||||||
|             Node *initFields; |  | ||||||
|         } structInit; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node **fieldInits; |  | ||||||
|             uint32_t count; |  | ||||||
|         } structInitFields; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *identifier; |  | ||||||
|             Node *argumentSequence; |  | ||||||
|             Node *genericArguments; |  | ||||||
|         } systemCall; |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *typeNode; |  | ||||||
|         } type; /* FIXME: this needs a refactor */ |  | ||||||
| 
 |  | ||||||
|         struct |  | ||||||
|         { |  | ||||||
|             Node *child; |  | ||||||
|             UnaryOperator operator; |  | ||||||
|         } unaryExpression; |  | ||||||
|     }; |  | ||||||
|     TypeTag *typeTag; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| const char *SyntaxKindString(SyntaxKind syntaxKind); |  | ||||||
| 
 | 
 | ||||||
| uint8_t IsPrimitiveType(Node *typeNode); | uint8_t IsPrimitiveType(Node *typeNode); | ||||||
| Node *MakePrimitiveTypeNode(PrimitiveType type); | Node* MakePrimitiveTypeNode( | ||||||
| Node *MakeCustomTypeNode(Node *identifierNode); |     PrimitiveType type | ||||||
| Node *MakeReferenceTypeNode(Node *typeNode); | ); | ||||||
| Node *MakeConcreteGenericTypeNode( | Node* MakeCustomTypeNode( | ||||||
|  |     char *string | ||||||
|  | ); | ||||||
|  | Node* MakeReferenceTypeNode( | ||||||
|  |     Node *typeNode | ||||||
|  | ); | ||||||
|  | Node* MakeTypeNode( | ||||||
|  |     Node *typeNode /* can be primitive, custom, or reference */ | ||||||
|  | ); | ||||||
|  | Node* MakeIdentifierNode( | ||||||
|  |     const char *id | ||||||
|  | ); | ||||||
|  | Node* MakeNumberNode( | ||||||
|  |     const char *numberString | ||||||
|  | ); | ||||||
|  | Node* MakeStringNode( | ||||||
|  |     const char *string | ||||||
|  | ); | ||||||
|  | Node* MakeStaticNode(); | ||||||
|  | Node* MakeFunctionModifiersNode( | ||||||
|  |     Node **pModifierNodes, | ||||||
|  |     uint32_t modifierCount | ||||||
|  | ); | ||||||
|  | Node* MakeUnaryNode( | ||||||
|  |     UnaryOperator operator, | ||||||
|  |     Node *child | ||||||
|  | ); | ||||||
|  | Node* MakeBinaryNode( | ||||||
|  |     BinaryOperator operator, | ||||||
|  |     Node *left, | ||||||
|  |     Node *right | ||||||
|  | ); | ||||||
|  | Node* MakeDeclarationNode( | ||||||
|  |     Node* typeNode, | ||||||
|  |     Node* identifierNode | ||||||
|  | ); | ||||||
|  | Node* MakeAssignmentNode( | ||||||
|  |     Node *left, | ||||||
|  |     Node *right | ||||||
|  | ); | ||||||
|  | Node* StartStatementSequenceNode( | ||||||
|  |     Node* statementNode | ||||||
|  | ); | ||||||
|  | Node* AddStatement( | ||||||
|  |     Node* statementSequenceNode, | ||||||
|  |     Node *statementNode | ||||||
|  | ); | ||||||
|  | Node* MakeReturnStatementNode( | ||||||
|  |     Node *expressionNode | ||||||
|  | ); | ||||||
|  | Node* MakeReturnVoidStatementNode(); | ||||||
|  | Node* StartFunctionSignatureArgumentsNode( | ||||||
|  |     Node *argumentNode | ||||||
|  | ); | ||||||
|  | Node* AddFunctionSignatureArgumentNode( | ||||||
|  |     Node *argumentsNode, | ||||||
|  |     Node *argumentNode | ||||||
|  | ); | ||||||
|  | Node* MakeEmptyFunctionSignatureArgumentsNode(); | ||||||
|  | Node* MakeGenericConstraintNode( | ||||||
|     Node *identifierNode, |     Node *identifierNode, | ||||||
|     Node *genericArgumentsNode); |     Node *interfaceNode | ||||||
| Node *MakeTypeNode(Node *typeNode); | ); | ||||||
| Node *MakeIdentifierNode(const char *id); | Node* StartGenericConstraintsNode(Node *genericNode); | ||||||
| Node *MakeNumberNode(const char *numberString); | Node* AddGenericConstraint( | ||||||
| Node *MakeStringNode(const char *string); |     Node *genericsNode, | ||||||
| Node *MakeStaticNode(); |     Node *genericNode | ||||||
| Node *MakeFunctionModifiersNode(Node **pModifierNodes, uint32_t modifierCount); | ); | ||||||
| Node *MakeUnaryNode(UnaryOperator operator, Node * child); | Node* MakeEmptyGenericConstraintsNode(); | ||||||
| Node *MakeBinaryNode(BinaryOperator operator, Node * left, Node *right); | Node* MakeFunctionSignatureNode( | ||||||
| Node *MakeDeclarationNode(Node *typeNode, Node *identifierNode); |  | ||||||
| Node *MakeAssignmentNode(Node *left, Node *right); |  | ||||||
| Node *StartStatementSequenceNode(Node *statementNode); |  | ||||||
| Node *AddStatement(Node *statementSequenceNode, Node *statementNode); |  | ||||||
| Node *MakeReturnStatementNode(Node *expressionNode); |  | ||||||
| Node *MakeReturnVoidStatementNode(); |  | ||||||
| Node *StartFunctionSignatureArgumentsNode(Node *argumentNode); |  | ||||||
| Node *AddFunctionSignatureArgumentNode(Node *argumentsNode, Node *argumentNode); |  | ||||||
| Node *MakeEmptyFunctionSignatureArgumentsNode(); |  | ||||||
| Node *MakeFunctionSignatureNode( |  | ||||||
|     Node *identifierNode, |     Node *identifierNode, | ||||||
|     Node *typeNode, |     Node *typeNode, | ||||||
|     Node *argumentsNode, |     Node *argumentsNode, | ||||||
|     Node *modifiersNode, |     Node *modifiersNode, | ||||||
|     Node *genericArgumentsNode); |     Node *genericConstraintsNode | ||||||
| Node *MakeFunctionDeclarationNode( |  | ||||||
|     Node *functionSignatureNode, |  | ||||||
|     Node *functionBodyNode); |  | ||||||
| Node *MakeGenericDeclarationNode(Node *identifierNode, Node *constraintNode); |  | ||||||
| Node *MakeEmptyGenericDeclarationsNode(); |  | ||||||
| Node *StartGenericDeclarationsNode(Node *genericDeclarationNode); |  | ||||||
| Node *AddGenericDeclaration( |  | ||||||
|     Node *genericDeclarationsNode, |  | ||||||
|     Node *genericDeclarationNode); |  | ||||||
| Node *MakeGenericArgumentNode(Node *typeNode); |  | ||||||
| Node *MakeEmptyGenericArgumentsNode(); |  | ||||||
| Node *StartGenericArgumentsNode(Node *genericArgumentNode); |  | ||||||
| Node *AddGenericArgument(Node *genericArgumentsNode, Node *genericArgumentNode); |  | ||||||
| Node *MakeGenericTypeNode(char *name); |  | ||||||
| Node *MakeStructDeclarationNode( |  | ||||||
|     Node *identifierNode, |  | ||||||
|     Node *declarationSequenceNode, |  | ||||||
|     Node *genericArgumentsNode); |  | ||||||
| Node *StartDeclarationSequenceNode(Node *declarationNode); |  | ||||||
| Node *AddDeclarationNode(Node *declarationSequenceNode, Node *declarationNode); |  | ||||||
| Node *StartFunctionArgumentSequenceNode(Node *argumentNode); |  | ||||||
| Node *AddFunctionArgumentNode(Node *argumentSequenceNode, Node *argumentNode); |  | ||||||
| Node *MakeEmptyFunctionArgumentSequenceNode(); |  | ||||||
| Node *MakeFunctionCallExpressionNode( |  | ||||||
|     Node *identifierNode, |  | ||||||
|     Node *argumentSequenceNode, |  | ||||||
|     Node *genericArgumentsNode); |  | ||||||
| Node *MakeSystemCallExpressionNode( |  | ||||||
|     Node *identifierNode, |  | ||||||
|     Node *argumentSequenceNode, |  | ||||||
|     Node *genericArgumentsNode); |  | ||||||
| Node *MakeAccessExpressionNode(Node *accessee, Node *accessor); |  | ||||||
| Node *MakeAllocNode(Node *typeNode); |  | ||||||
| Node *MakeIfNode(Node *expressionNode, Node *statementSequenceNode); |  | ||||||
| Node *MakeIfElseNode( |  | ||||||
|     Node *ifNode, |  | ||||||
|     Node *elseNode /* can be a conditional or a statement sequence */ |  | ||||||
| ); | ); | ||||||
| Node *MakeForLoopNode( | Node* MakeFunctionDeclarationNode( | ||||||
|  |     Node *functionSignatureNode, | ||||||
|  |     Node *functionBodyNode | ||||||
|  | ); | ||||||
|  | Node* MakeStructDeclarationNode( | ||||||
|  |     Node *identifierNode, | ||||||
|  |     Node *declarationSequenceNode | ||||||
|  | ); | ||||||
|  | Node* MakeInterfaceDeclarationNode( | ||||||
|  |     Node *identifierNode, | ||||||
|  |     Node *declarationSequenceNode | ||||||
|  | ); | ||||||
|  | Node* StartDeclarationSequenceNode( | ||||||
|  |     Node *declarationNode | ||||||
|  | ); | ||||||
|  | Node* AddDeclarationNode( | ||||||
|  |     Node *declarationSequenceNode, | ||||||
|  |     Node *declarationNode | ||||||
|  | ); | ||||||
|  | Node *StartFunctionArgumentSequenceNode( | ||||||
|  |     Node *argumentNode | ||||||
|  | ); | ||||||
|  | Node *AddFunctionArgumentNode( | ||||||
|  |     Node *argumentSequenceNode, | ||||||
|  |     Node *argumentNode | ||||||
|  | ); | ||||||
|  | Node *MakeEmptyFunctionArgumentSequenceNode(); | ||||||
|  | Node* MakeFunctionCallExpressionNode( | ||||||
|  |     Node *identifierNode, | ||||||
|  |     Node *argumentSequenceNode | ||||||
|  | ); | ||||||
|  | Node* MakeAccessExpressionNode( | ||||||
|  |     Node *accessee, | ||||||
|  |     Node *accessor | ||||||
|  | ); | ||||||
|  | Node* MakeAllocNode( | ||||||
|  |     Node *typeNode | ||||||
|  | ); | ||||||
|  | Node* MakeIfNode( | ||||||
|  |     Node *expressionNode, | ||||||
|  |     Node *statementSequenceNode | ||||||
|  | ); | ||||||
|  | Node* MakeIfElseNode( | ||||||
|  |     Node *ifNode, | ||||||
|  |     Node *statementSequenceNode | ||||||
|  | ); | ||||||
|  | Node* MakeForLoopNode( | ||||||
|     Node *identifierNode, |     Node *identifierNode, | ||||||
|     Node *startNumberNode, |     Node *startNumberNode, | ||||||
|     Node *endNumberNode, |     Node *endNumberNode, | ||||||
|     Node *statementSequenceNode); |     Node *statementSequenceNode | ||||||
| Node *MakeFieldInitNode(Node *identifierNode, Node *expressionNode); | ); | ||||||
| Node *StartStructInitFieldsNode(Node *fieldInitNode); |  | ||||||
| Node *AddFieldInitNode(Node *structInitFieldsNode, Node *fieldInitNode); |  | ||||||
| Node *MakeEmptyFieldInitNode(); |  | ||||||
| Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode); |  | ||||||
| 
 | 
 | ||||||
| void PrintNode(Node *node, uint32_t tabCount); | void PrintTree(Node *node, uint32_t tabCount); | ||||||
| const char *SyntaxKindString(SyntaxKind syntaxKind); |  | ||||||
| 
 |  | ||||||
| /* Helper function for applying a void function generically over the children of
 |  | ||||||
|  * an AST node. Used for functions that need to traverse the entire tree but |  | ||||||
|  * only perform operations on a subset of node types. Such functions can match |  | ||||||
|  * the syntaxKinds relevant to their purpose and invoke this function in all |  | ||||||
|  * other cases. */ |  | ||||||
| void Recurse(Node *node, void (*func)(Node *)); |  | ||||||
| 
 |  | ||||||
| void LinkParentPointers(Node *node, Node *prev); |  | ||||||
| 
 |  | ||||||
| TypeTag *MakeTypeTag(Node *node); |  | ||||||
| char *TypeTagToString(TypeTag *tag); |  | ||||||
| uint8_t TypeTagEqual(TypeTag *typeTagA, TypeTag *typeTagB); |  | ||||||
| 
 |  | ||||||
| Node *LookupIdNode(Node *current, Node *prev, char *target); |  | ||||||
| 
 | 
 | ||||||
| #endif /* WRAITH_AST_H */ | #endif /* WRAITH_AST_H */ | ||||||
|  |  | ||||||
							
								
								
									
										2280
									
								
								src/codegen.c
								
								
								
								
							
							
						
						
									
										2280
									
								
								src/codegen.c
								
								
								
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										46
									
								
								src/main.c
								
								
								
								
							
							
						
						
									
										46
									
								
								src/main.c
								
								
								
								
							|  | @ -1,9 +1,8 @@ | ||||||
| #include "../lib/dropt/dropt.h" |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  | #include "../lib/dropt/dropt.h" | ||||||
| 
 | 
 | ||||||
| #include "codegen.h" |  | ||||||
| #include "parser.h" | #include "parser.h" | ||||||
| #include "validation.h" | #include "codegen.h" | ||||||
| 
 | 
 | ||||||
| int main(int argc, char *argv[]) | int main(int argc, char *argv[]) | ||||||
| { | { | ||||||
|  | @ -14,27 +13,10 @@ int main(int argc, char *argv[]) | ||||||
|     int exitCode = EXIT_SUCCESS; |     int exitCode = EXIT_SUCCESS; | ||||||
| 
 | 
 | ||||||
|     dropt_option options[] = { |     dropt_option options[] = { | ||||||
|         {'h', |         { 'h', "help", "Shows help.", NULL, dropt_handle_bool, &showHelp, dropt_attr_halt }, | ||||||
|          "help", |         { 'v', "parse-verbose", "Shows verbose parser output.", NULL, dropt_handle_bool, &parseVerbose }, | ||||||
|          "Shows help.", |         { 'O', "optimize", "Sets optimization level of the output IR. Must be a value between 0 and 3.", "number", dropt_handle_uint, &optimizationLevel }, | ||||||
|          NULL, |         { 0 } /* Required sentinel value. */ | ||||||
|          dropt_handle_bool, |  | ||||||
|          &showHelp, |  | ||||||
|          dropt_attr_halt}, |  | ||||||
|         {'v', |  | ||||||
|          "parse-verbose", |  | ||||||
|          "Shows verbose parser output.", |  | ||||||
|          NULL, |  | ||||||
|          dropt_handle_bool, |  | ||||||
|          &parseVerbose}, |  | ||||||
|         {'O', |  | ||||||
|          "optimize", |  | ||||||
|          "Sets optimization level of the output IR. Must be a value between 0 " |  | ||||||
|          "and 3.", |  | ||||||
|          "number", |  | ||||||
|          dropt_handle_uint, |  | ||||||
|          &optimizationLevel}, |  | ||||||
|         {0} /* Required sentinel value. */ |  | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     dropt_context *droptContext = dropt_new_context(options); |     dropt_context *droptContext = dropt_new_context(options); | ||||||
|  | @ -50,13 +32,10 @@ int main(int argc, char *argv[]) | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         char **rest = dropt_parse(droptContext, -1, &argv[1]); |         char** rest = dropt_parse(droptContext, -1, &argv[1]); | ||||||
|         if (dropt_get_error(droptContext) != dropt_error_none) |         if (dropt_get_error(droptContext) != dropt_error_none) | ||||||
|         { |         { | ||||||
|             fprintf( |             fprintf(stderr, "wraith: %s\n", dropt_get_error_message(droptContext)); | ||||||
|                 stderr, |  | ||||||
|                 "wraith: %s\n", |  | ||||||
|                 dropt_get_error_message(droptContext)); |  | ||||||
|             exitCode = EXIT_FAILURE; |             exitCode = EXIT_FAILURE; | ||||||
|         } |         } | ||||||
|         else if (showHelp) |         else if (showHelp) | ||||||
|  | @ -85,15 +64,6 @@ int main(int argc, char *argv[]) | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|                     LinkParentPointers(rootNode, NULL); |  | ||||||
|                     /* FIXME: ValidateIdentifiers should return some sort of
 |  | ||||||
|                               error status object. */ |  | ||||||
|                     ValidateIdentifiers(rootNode); |  | ||||||
|                     TagIdentifierTypes(rootNode); |  | ||||||
|                     ConvertCustomsToGenerics(rootNode); |  | ||||||
|                     PrintNode(rootNode, 0); |  | ||||||
| 
 |  | ||||||
|                     printf("Beginning codegen.\n"); |  | ||||||
|                     exitCode = Codegen(rootNode, optimizationLevel); |                     exitCode = Codegen(rootNode, optimizationLevel); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 
 | 
 | ||||||
| #include "ast.h" |  | ||||||
| #include "y.tab.h" | #include "y.tab.h" | ||||||
|  | #include "ast.h" | ||||||
| 
 | 
 | ||||||
| extern FILE *yyin; | extern FILE *yyin; | ||||||
| extern int yydebug; | extern int yydebug; | ||||||
|  | @ -31,7 +31,7 @@ int Parse(char *inputFilename, Node **pRootNode, uint8_t parseVerbose) | ||||||
|     { |     { | ||||||
|         if (parseVerbose) |         if (parseVerbose) | ||||||
|         { |         { | ||||||
|             PrintNode(*pRootNode, 0); |             PrintTree(*pRootNode, 0); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     else if (result == 1) |     else if (result == 1) | ||||||
|  |  | ||||||
							
								
								
									
										38
									
								
								src/util.c
								
								
								
								
							
							
						
						
									
										38
									
								
								src/util.c
								
								
								
								
							|  | @ -1,38 +0,0 @@ | ||||||
| #include "util.h" |  | ||||||
| 
 |  | ||||||
| #include <stdlib.h> |  | ||||||
| 
 |  | ||||||
| char *strdup(const char *s) |  | ||||||
| { |  | ||||||
|     size_t slen = strlen(s); |  | ||||||
|     char *result = (char *)malloc(sizeof(char) * (slen + 1)); |  | ||||||
|     if (result == NULL) |  | ||||||
|     { |  | ||||||
|         return NULL; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     memcpy(result, s, slen + 1); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| char *w_strcat(char *s, char *s2) |  | ||||||
| { |  | ||||||
|     size_t slen = strlen(s); |  | ||||||
|     size_t slen2 = strlen(s2); |  | ||||||
|     s = realloc(s, sizeof(char) * (slen + slen2 + 1)); |  | ||||||
|     strcat(s, s2); |  | ||||||
|     return s; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uint64_t str_hash(char *str) |  | ||||||
| { |  | ||||||
|     uint64_t hash = 5381; |  | ||||||
|     size_t c; |  | ||||||
| 
 |  | ||||||
|     while ((c = *str++)) |  | ||||||
|     { |  | ||||||
|         hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return hash; |  | ||||||
| } |  | ||||||
							
								
								
									
										11
									
								
								src/util.h
								
								
								
								
							
							
						
						
									
										11
									
								
								src/util.h
								
								
								
								
							|  | @ -1,11 +0,0 @@ | ||||||
| #ifndef WRAITH_UTIL_H |  | ||||||
| #define WRAITH_UTIL_H |  | ||||||
| 
 |  | ||||||
| #include <stdint.h> |  | ||||||
| #include <string.h> |  | ||||||
| 
 |  | ||||||
| char *strdup(const char *s); |  | ||||||
| char *w_strcat(char *s, char *s2); |  | ||||||
| uint64_t str_hash(char *str); |  | ||||||
| 
 |  | ||||||
| #endif /* WRAITH_UTIL_H */ |  | ||||||
							
								
								
									
										493
									
								
								src/validation.c
								
								
								
								
							
							
						
						
									
										493
									
								
								src/validation.c
								
								
								
								
							|  | @ -1,493 +0,0 @@ | ||||||
| #include "validation.h" |  | ||||||
| 
 |  | ||||||
| #include <stdbool.h> |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <string.h> |  | ||||||
| 
 |  | ||||||
| Node *GetIdFromStruct(Node *structDecl) |  | ||||||
| { |  | ||||||
|     if (structDecl->syntaxKind != StructDeclaration) |  | ||||||
|     { |  | ||||||
|         fprintf( |  | ||||||
|             stderr, |  | ||||||
|             "wraith: Attempted to call GetIdFromStruct on node with kind: " |  | ||||||
|             "%s.\n", |  | ||||||
|             SyntaxKindString(structDecl->syntaxKind)); |  | ||||||
|         return NULL; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return structDecl->structDeclaration.identifier; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Node *GetIdFromFunction(Node *funcDecl) |  | ||||||
| { |  | ||||||
|     if (funcDecl->syntaxKind != FunctionDeclaration) |  | ||||||
|     { |  | ||||||
|         fprintf( |  | ||||||
|             stderr, |  | ||||||
|             "wraith: Attempted to call GetIdFromFunction on node with kind: " |  | ||||||
|             "%s.\n", |  | ||||||
|             SyntaxKindString(funcDecl->syntaxKind)); |  | ||||||
|         return NULL; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     Node *sig = funcDecl->functionDeclaration.functionSignature; |  | ||||||
|     return sig->functionSignature.identifier; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Node *GetIdFromDeclaration(Node *decl) |  | ||||||
| { |  | ||||||
|     if (decl->syntaxKind != Declaration) |  | ||||||
|     { |  | ||||||
|         fprintf( |  | ||||||
|             stderr, |  | ||||||
|             "wraith: Attempted to call GetIdFromDeclaration on node with kind: " |  | ||||||
|             "%s.\n", |  | ||||||
|             SyntaxKindString(decl->syntaxKind)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return decl->declaration.identifier; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool AssignmentHasDeclaration(Node *assign) |  | ||||||
| { |  | ||||||
|     return ( |  | ||||||
|         assign->syntaxKind == Assignment && |  | ||||||
|         assign->assignmentStatement.left->syntaxKind == Declaration); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Node *GetIdFromAssignment(Node *assign) |  | ||||||
| { |  | ||||||
|     if (assign->syntaxKind != Assignment) |  | ||||||
|     { |  | ||||||
|         fprintf( |  | ||||||
|             stderr, |  | ||||||
|             "wraith: Attempted to call GetIdFromAssignment on node with kind: " |  | ||||||
|             "%s.\n", |  | ||||||
|             SyntaxKindString(assign->syntaxKind)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (AssignmentHasDeclaration(assign)) |  | ||||||
|     { |  | ||||||
|         return GetIdFromDeclaration(assign->assignmentStatement.left); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool NodeMayHaveId(Node *node) |  | ||||||
| { |  | ||||||
|     switch (node->syntaxKind) |  | ||||||
|     { |  | ||||||
|     case StructDeclaration: |  | ||||||
|     case FunctionDeclaration: |  | ||||||
|     case Declaration: |  | ||||||
|     case Assignment: |  | ||||||
|         return true; |  | ||||||
|     default: |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Node *TryGetId(Node *node) |  | ||||||
| { |  | ||||||
|     switch (node->syntaxKind) |  | ||||||
|     { |  | ||||||
|     case Assignment: |  | ||||||
|         return GetIdFromAssignment(node); |  | ||||||
|     case Declaration: |  | ||||||
|         return GetIdFromDeclaration(node); |  | ||||||
|     case FunctionDeclaration: |  | ||||||
|         return GetIdFromFunction(node); |  | ||||||
|     case StructDeclaration: |  | ||||||
|         return GetIdFromStruct(node); |  | ||||||
|     default: |  | ||||||
|         return NULL; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Node *LookupFunctionArgId(Node *funcDecl, char *target) |  | ||||||
| { |  | ||||||
|     Node *args = funcDecl->functionDeclaration.functionSignature |  | ||||||
|                      ->functionSignature.arguments; |  | ||||||
| 
 |  | ||||||
|     uint32_t i; |  | ||||||
|     for (i = 0; i < args->functionArgumentSequence.count; i += 1) |  | ||||||
|     { |  | ||||||
|         Node *arg = args->functionArgumentSequence.sequence[i]; |  | ||||||
|         if (arg->syntaxKind != Declaration) |  | ||||||
|         { |  | ||||||
|             fprintf( |  | ||||||
|                 stderr, |  | ||||||
|                 "wraith: Encountered %s node in function signature args " |  | ||||||
|                 "list.\n", |  | ||||||
|                 SyntaxKindString(arg->syntaxKind)); |  | ||||||
|             continue; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Node *argId = GetIdFromDeclaration(arg); |  | ||||||
|         if (argId != NULL && strcmp(target, argId->identifier.name) == 0) |  | ||||||
|             return argId; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Node *LookupStructInternalId(Node *structDecl, char *target) |  | ||||||
| { |  | ||||||
|     Node *decls = structDecl->structDeclaration.declarationSequence; |  | ||||||
| 
 |  | ||||||
|     uint32_t i; |  | ||||||
|     for (i = 0; i < decls->declarationSequence.count; i += 1) |  | ||||||
|     { |  | ||||||
|         Node *match = TryGetId(decls->declarationSequence.sequence[i]); |  | ||||||
|         if (match != NULL && strcmp(target, match->identifier.name) == 0) |  | ||||||
|             return match; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Node *InspectNode(Node *node, char *target) |  | ||||||
| { |  | ||||||
|     /* If this node may have an identifier declaration inside it, attempt to
 |  | ||||||
|      * look up the identifier |  | ||||||
|      * node itself, returning it if it matches the given target name. */ |  | ||||||
|     if (NodeMayHaveId(node)) |  | ||||||
|     { |  | ||||||
|         Node *candidateId = TryGetId(node); |  | ||||||
|         if (candidateId != NULL && |  | ||||||
|             strcmp(target, candidateId->identifier.name) == 0) |  | ||||||
|             return candidateId; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* If the candidate node was not the one we wanted, but the node node is a
 |  | ||||||
|      * function declaration, it's possible that the identifier we want is one of |  | ||||||
|      * the function's parameters rather than the function's name itself. */ |  | ||||||
|     if (node->syntaxKind == FunctionDeclaration) |  | ||||||
|     { |  | ||||||
|         Node *match = LookupFunctionArgId(node, target); |  | ||||||
|         if (match != NULL) |  | ||||||
|             return match; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* Likewise if the node node is a struct declaration, inspect the struct's
 |  | ||||||
|      * internals |  | ||||||
|      * to see if a top-level definition is the one we're looking for. */ |  | ||||||
|     if (node->syntaxKind == StructDeclaration) |  | ||||||
|     { |  | ||||||
|         Node *match = LookupStructInternalId(node, target); |  | ||||||
|         if (match != NULL) |  | ||||||
|             return match; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* FIXME: Handle staged lookups for AccessExpressions. */ |  | ||||||
| /* FIXME: Similar to above, disallow inspection of struct internals outside of
 |  | ||||||
|  *        AccessExpressions. */ |  | ||||||
| Node *LookupId(Node *current, Node *prev, char *target) |  | ||||||
| { |  | ||||||
|     if (current == NULL) |  | ||||||
|         return NULL; |  | ||||||
| 
 |  | ||||||
|     Node *match; |  | ||||||
| 
 |  | ||||||
|     /* First inspect the current node to see if it contains the target
 |  | ||||||
|      * identifier. */ |  | ||||||
|     match = InspectNode(current, target); |  | ||||||
|     if (match != NULL) |  | ||||||
|         return match; |  | ||||||
| 
 |  | ||||||
|     /* If this is the start of our search, we should not attempt to look at
 |  | ||||||
|      * child nodes. Only looking up the AST is valid at this point. |  | ||||||
|      * |  | ||||||
|      * This has the notable side-effect that this function will return NULL if |  | ||||||
|      * you attempt to look up a struct's internals starting from the node |  | ||||||
|      * representing the struct itself. The same is true for functions. */ |  | ||||||
|     if (prev == NULL) |  | ||||||
|         return LookupId(current->parent, current, target); |  | ||||||
| 
 |  | ||||||
|     uint32_t i; |  | ||||||
|     uint32_t idxLimit; |  | ||||||
|     switch (current->syntaxKind) |  | ||||||
|     { |  | ||||||
|     case DeclarationSequence: |  | ||||||
|         for (i = 0; i < current->declarationSequence.count; i += 1) |  | ||||||
|         { |  | ||||||
|             Node *decl = current->declarationSequence.sequence[i]; |  | ||||||
|             match = InspectNode(decl, target); |  | ||||||
|             if (match != NULL) |  | ||||||
|                 return match; |  | ||||||
|         } |  | ||||||
|         break; |  | ||||||
|     case StatementSequence: |  | ||||||
|         idxLimit = current->statementSequence.count; |  | ||||||
|         for (i = 0; i < current->statementSequence.count; i += 1) |  | ||||||
|         { |  | ||||||
|             if (current->statementSequence.sequence[i] == prev) |  | ||||||
|             { |  | ||||||
|                 idxLimit = i; |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         for (i = 0; i < idxLimit; i += 1) |  | ||||||
|         { |  | ||||||
|             Node *stmt = current->statementSequence.sequence[i]; |  | ||||||
|             if (stmt == prev) |  | ||||||
|                 break; |  | ||||||
| 
 |  | ||||||
|             match = InspectNode(stmt, target); |  | ||||||
|             if (match != NULL) |  | ||||||
|                 return match; |  | ||||||
|         } |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return LookupId(current->parent, current, target); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* FIXME: This function should be extended to handle multi-stage ID lookups for
 |  | ||||||
|  *        AccessExpression nodes. */ |  | ||||||
| /* FIXME: Make this function return an error status object of some kind.
 |  | ||||||
|  *        A non-OK status should halt compilation. */ |  | ||||||
| void ValidateIdentifiers(Node *node) |  | ||||||
| { |  | ||||||
|     if (node == NULL) |  | ||||||
|         return; |  | ||||||
| 
 |  | ||||||
|     /* Skip over generic arguments. They contain Identifiers but are not
 |  | ||||||
|      * actually identifiers, they declare types. */ |  | ||||||
|     if (node->syntaxKind == GenericDeclarations) |  | ||||||
|         return; |  | ||||||
| 
 |  | ||||||
|     if (node->syntaxKind != Identifier) |  | ||||||
|     { |  | ||||||
|         Recurse(node, *ValidateIdentifiers); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     char *name = node->identifier.name; |  | ||||||
|     Node *decl = LookupId(node, NULL, name); |  | ||||||
|     if (decl == NULL) |  | ||||||
|     { |  | ||||||
|         /* FIXME: Express this case as an error with AST information, see the
 |  | ||||||
|          *        FIXME comment above. */ |  | ||||||
|         fprintf( |  | ||||||
|             stderr, |  | ||||||
|             "wraith: Could not find definition of identifier %s.\n", |  | ||||||
|             name); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* FIXME: This function should be extended to handle multi-stage ID lookups for
 |  | ||||||
|  *        AccessExpression nodes. */ |  | ||||||
| void TagIdentifierTypes(Node *node) |  | ||||||
| { |  | ||||||
|     if (node == NULL) |  | ||||||
|         return; |  | ||||||
| 
 |  | ||||||
|     switch (node->syntaxKind) |  | ||||||
|     { |  | ||||||
|     case AllocExpression: |  | ||||||
|         node->typeTag = MakeTypeTag(node); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     case Declaration: |  | ||||||
|         node->declaration.identifier->typeTag = MakeTypeTag(node); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     case FunctionDeclaration: |  | ||||||
|         node->functionDeclaration.functionSignature->functionSignature |  | ||||||
|             .identifier->typeTag = MakeTypeTag(node); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     case StructDeclaration: |  | ||||||
|         node->structDeclaration.identifier->typeTag = MakeTypeTag(node); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     case GenericDeclaration: |  | ||||||
|         node->genericDeclaration.identifier->typeTag = MakeTypeTag(node); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     case Type: |  | ||||||
|         node->typeTag = MakeTypeTag(node); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     case Identifier: |  | ||||||
|     { |  | ||||||
|         if (node->typeTag != NULL) |  | ||||||
|             return; |  | ||||||
| 
 |  | ||||||
|         char *name = node->identifier.name; |  | ||||||
|         Node *declaration = LookupId(node, NULL, name); |  | ||||||
|         /* FIXME: Remove this case once ValidateIdentifiers returns error status
 |  | ||||||
|          * info and halts compilation. See ValidateIdentifiers FIXME. */ |  | ||||||
|         if (declaration == NULL) |  | ||||||
|         { |  | ||||||
|             TypeTag *tag = (TypeTag *)malloc(sizeof(TypeTag)); |  | ||||||
|             tag->type = Unknown; |  | ||||||
|             node->typeTag = tag; |  | ||||||
|         } |  | ||||||
|         else |  | ||||||
|         { |  | ||||||
|             node->typeTag = declaration->typeTag; |  | ||||||
|         } |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     Recurse(node, *TagIdentifierTypes); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Node *LookupType(Node *current, char *target) |  | ||||||
| { |  | ||||||
|     if (current == NULL) |  | ||||||
|         return NULL; |  | ||||||
| 
 |  | ||||||
|     switch (current->syntaxKind) |  | ||||||
|     { |  | ||||||
|     /* If we've encountered a function declaration, check to see if it's generic
 |  | ||||||
|      * and, if so, if one of its type parameters is the target. */ |  | ||||||
|     case FunctionDeclaration: |  | ||||||
|     { |  | ||||||
|         Node *typeArgs = current->functionDeclaration.functionSignature |  | ||||||
|                              ->functionSignature.genericDeclarations; |  | ||||||
|         uint32_t i; |  | ||||||
|         for (i = 0; i < typeArgs->genericDeclarations.count; i += 1) |  | ||||||
|         { |  | ||||||
|             Node *arg = typeArgs->genericDeclarations.declarations[i]; |  | ||||||
|             Node *argId = arg->genericDeclaration.identifier; |  | ||||||
|             char *argName = argId->identifier.name; |  | ||||||
|             /* note: return the GenericDeclaration, not the Identifier, so that
 |  | ||||||
|              * the caller can differentiate between generics and customs. */ |  | ||||||
|             if (strcmp(target, argName) == 0) |  | ||||||
|             { |  | ||||||
|                 return arg; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return LookupType(current->parent, target); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     case StructDeclaration: |  | ||||||
|     { |  | ||||||
|         uint32_t i; |  | ||||||
|         Node *typeArgs = current->structDeclaration.genericDeclarations; |  | ||||||
|         for (i = 0; i < typeArgs->genericDeclarations.count; i += 1) |  | ||||||
|         { |  | ||||||
|             Node *arg = typeArgs->genericDeclarations.declarations[i]; |  | ||||||
|             Node *argId = arg->genericDeclaration.identifier; |  | ||||||
|             char *argName = argId->identifier.name; |  | ||||||
|             /* note: return the GenericDeclaration, not the Identifier, so that
 |  | ||||||
|              * the caller can differentiate between generics and customs. */ |  | ||||||
|             if (strcmp(target, argName) == 0) |  | ||||||
|             { |  | ||||||
|                 return arg; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Node *structId = GetIdFromStruct(current); |  | ||||||
|         if (strcmp(target, structId->identifier.name) == 0) |  | ||||||
|         { |  | ||||||
|             return structId; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return LookupType(current->parent, target); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* If we encounter a declaration sequence, search each of its children for
 |  | ||||||
|      * struct definitions in case one of them is the target. */ |  | ||||||
|     case DeclarationSequence: |  | ||||||
|     { |  | ||||||
|         uint32_t i; |  | ||||||
|         for (i = 0; i < current->declarationSequence.count; i += 1) |  | ||||||
|         { |  | ||||||
|             Node *decl = current->declarationSequence.sequence[i]; |  | ||||||
|             if (decl->syntaxKind == StructDeclaration) |  | ||||||
|             { |  | ||||||
|                 Node *structId = GetIdFromStruct(decl); |  | ||||||
|                 if (strcmp(target, structId->identifier.name) == 0) |  | ||||||
|                     return structId; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return LookupType(current->parent, target); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     default: |  | ||||||
|         return LookupType(current->parent, target); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* FIXME: This function should be modified to handle type parameters over
 |  | ||||||
|  * structs. */ |  | ||||||
| void ConvertCustomsToGenerics(Node *node) |  | ||||||
| { |  | ||||||
|     if (node == NULL) |  | ||||||
|         return; |  | ||||||
| 
 |  | ||||||
|     switch (node->syntaxKind) |  | ||||||
|     { |  | ||||||
|     case Declaration: |  | ||||||
|     { |  | ||||||
|         Node *id = node->declaration.identifier; |  | ||||||
|         Node *type = node->declaration.type->type.typeNode; |  | ||||||
|         if (type->syntaxKind == CustomTypeNode) |  | ||||||
|         { |  | ||||||
|             char *target = id->typeTag->value.customType; |  | ||||||
|             Node *typeLookup = LookupType(node, target); |  | ||||||
|             if (typeLookup != NULL && |  | ||||||
|                 typeLookup->syntaxKind == GenericDeclaration) |  | ||||||
|             { |  | ||||||
|                 id->typeTag->type = Generic; |  | ||||||
|                 free(node->declaration.type); |  | ||||||
|                 node->declaration.type = |  | ||||||
|                     MakeGenericTypeNode(id->typeTag->value.genericType); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     case FunctionSignature: |  | ||||||
|     { |  | ||||||
|         Node *id = node->functionSignature.identifier; |  | ||||||
|         Node *type = node->functionSignature.type->type.typeNode; |  | ||||||
|         if (type->syntaxKind == CustomTypeNode) |  | ||||||
|         { |  | ||||||
|             char *target = id->typeTag->value.customType; |  | ||||||
|             Node *typeLookup = LookupType(node, target); |  | ||||||
|             if (typeLookup != NULL && |  | ||||||
|                 typeLookup->syntaxKind == GenericDeclaration) |  | ||||||
|             { |  | ||||||
|                 id->typeTag->type = Generic; |  | ||||||
|                 free(node->functionSignature.type); |  | ||||||
|                 node->functionSignature.type = |  | ||||||
|                     MakeGenericTypeNode(id->typeTag->value.genericType); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     case GenericArgument: |  | ||||||
|     { |  | ||||||
|         Node *typeNode = node->genericArgument.type; |  | ||||||
|         if (typeNode->typeTag->type == Custom) |  | ||||||
|         { |  | ||||||
|             char *target = typeNode->typeTag->value.customType; |  | ||||||
|             Node *typeLookup = LookupType(node, target); |  | ||||||
|             if (typeLookup != NULL && |  | ||||||
|                 typeLookup->syntaxKind == GenericDeclaration) |  | ||||||
|             { |  | ||||||
|                 typeNode->typeTag->type = Generic; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     Recurse(node, *ConvertCustomsToGenerics); |  | ||||||
| } |  | ||||||
|  | @ -1,10 +0,0 @@ | ||||||
| #ifndef WRAITH_VALIDATION_H |  | ||||||
| #define WRAITH_VALIDATION_H |  | ||||||
| 
 |  | ||||||
| #include "ast.h" |  | ||||||
| 
 |  | ||||||
| void ValidateIdentifiers(Node *node); |  | ||||||
| void TagIdentifierTypes(Node *node); |  | ||||||
| void ConvertCustomsToGenerics(Node *node); |  | ||||||
| 
 |  | ||||||
| #endif /* WRAITH_VALIDATION_H */ |  | ||||||
		Loading…
	
		Reference in New Issue