@@ -34,6 +34,7 @@ import {CallExpressionCodeGenerator} from "./code-generation/call-expression";
3434import { PropertyAccessExpressionCodeGenerator } from "./code-generation/property-access-expression" ;
3535import { TryStatementGenerator } from "./code-generation/try-statement" ;
3636import { PostfixUnaryExpressionCodeGenerator } from "./code-generation/postfix-unary-expression" ;
37+ import { FunctionDeclarationCodeGenerator } from "./code-generation/function-declaration" ;
3738
3839export function emitCondition (
3940 condition : ts . Expression ,
@@ -48,81 +49,6 @@ export function emitCondition(
4849 builder . createCondBr ( conditionBoolValue . getValue ( ) , positiveBlock , negativeBlock ) ;
4950}
5051
51- export function passFunctionDeclaration ( parent : ts . FunctionDeclaration , ctx : Context , builder : llvm . IRBuilder ) {
52- if ( ! parent . name || ! parent . name . escapedText ) {
53- throw Error ( 'Function must be declared with name' ) ;
54- }
55-
56- if ( ! parent . type ) {
57- throw Error ( 'Function must be declared with return type' ) ;
58- }
59-
60- let returnType = NativeTypeResolver . getType ( ctx . typeChecker . getTypeFromTypeNode ( parent . type ) , ctx ) . getType ( ) ;
61- let fnType = llvm . FunctionType . get (
62- returnType ,
63- parent . parameters . map ( ( parameter ) => {
64- if ( parameter . type ) {
65- const nativeType = NativeTypeResolver . getType ( ctx . typeChecker . getTypeFromTypeNode ( parameter . type ) , ctx ) ;
66- if ( nativeType ) {
67- return nativeType . getType ( ) ;
68- }
69- }
70-
71- throw new UnsupportedError (
72- parameter ,
73- `Unsupported parameter`
74- ) ;
75- } ) ,
76- false
77- ) ;
78- let fn = llvm . Function . create ( fnType , llvm . LinkageTypes . ExternalLinkage , < string > parent . name . escapedText , ctx . llvmModule ) ;
79-
80- let block = llvm . BasicBlock . create ( ctx . llvmContext , 'Entry' , fn ) ;
81- let irBuilder = new llvm . IRBuilder ( block ) ;
82-
83- for ( const argument of fn . getArguments ( ) ) {
84- const parameter = parent . parameters [ argument . argumentNumber ] ;
85- if ( parameter ) {
86- argument . name = < string > ( < ts . Identifier > parameter . name ) . escapedText ;
87- ctx . scope . variables . set ( argument . name , new Primitive ( argument ) ) ;
88- } else {
89- throw new UnsupportedError (
90- parameter ,
91- `Unsupported parameter`
92- ) ;
93- }
94- }
95-
96-
97- // Store to return back
98- const enclosureFnStore = ctx . scope . enclosureFunction ;
99-
100- ctx . scope . enclosureFunction = {
101- llvmFunction : fn ,
102- declaration : parent
103- } ;
104-
105- if ( parent . body ) {
106- for ( const stmt of parent . body . statements ) {
107- passStatement ( stmt , ctx , irBuilder ) ;
108- }
109- }
110-
111- // store back
112- ctx . scope . enclosureFunction = enclosureFnStore ;
113-
114- if ( returnType . isVoidTy ( ) ) {
115- if ( ! block . getTerminator ( ) ) {
116- irBuilder . createRetVoid ( ) ;
117- }
118-
119- const nextBlock = irBuilder . getInsertBlock ( ) ;
120- if ( ! nextBlock . getTerminator ( ) ) {
121- irBuilder . createRetVoid ( ) ;
122- }
123- }
124- }
125-
12652export function buildFromStringValue ( node : ts . StringLiteral , ctx : Context , builder : llvm . IRBuilder ) : Value {
12753 return new Primitive (
12854 builder . createGlobalStringPtr (
@@ -457,7 +383,7 @@ export function passStatement(stmt: ts.Statement, ctx: Context, builder: llvm.IR
457383 buildFromExpression ( < any > stmt , ctx , builder ) ;
458384 break ;
459385 case ts . SyntaxKind . FunctionDeclaration :
460- passFunctionDeclaration ( stmt as ts . FunctionDeclaration , ctx , builder ) ;
386+ new FunctionDeclarationCodeGenerator ( ) . generate ( stmt as ts . FunctionDeclaration , ctx , builder ) ;
461387 break ;
462388 case ts . SyntaxKind . ReturnStatement :
463389 new ReturnStatementCodeGenerator ( ) . generate ( stmt as ts . ReturnStatement , ctx , builder ) ;
0 commit comments