@@ -6,6 +6,10 @@ import {Context} from "./context";
66import { NativeTypeResolver } from "./native-type-resolver" ;
77import UnsupportedError from "../error/unsupported.error" ;
88import { NativeType } from "./native-type" ;
9+ import { RUNTIME_DEFINITION_FILE } from "@static-script/runtime" ;
10+ import { LANGUAGE_DEFINITION_FILE } from "../../constants" ;
11+ import { CMangler } from "./c.mangler" ;
12+ import { ManglerInterface } from "./mangler.interface" ;
913
1014export function passReturnStatement ( parent : ts . ReturnStatement , ctx : Context , builder : llvm . IRBuilder ) {
1115 if ( ! parent . expression ) {
@@ -162,6 +166,35 @@ function buildFromCallExpression(
162166 ) ;
163167}
164168
169+ function declareFunctionFromDefinition (
170+ stmt : ts . FunctionDeclaration ,
171+ ctx : Context ,
172+ builder : llvm . IRBuilder ,
173+ mangler : ManglerInterface
174+ ) : llvm . Function {
175+ let fnType = llvm . FunctionType . get (
176+ stmt . type ? NativeTypeResolver . getType ( ctx . typeChecker . getTypeFromTypeNode ( stmt . type ) , ctx ) . getType ( ) : llvm . Type . getVoidTy ( ctx . llvmContext ) ,
177+ stmt . parameters . map ( ( parameters ) => {
178+ if ( parameters . type ) {
179+ return NativeTypeResolver . getType ( ctx . typeChecker . getTypeFromTypeNode ( parameters . type ) , ctx ) . getType ( )
180+ }
181+
182+ throw new UnsupportedError (
183+ stmt ,
184+ `Unsupported parameter`
185+ ) ;
186+ } ) ,
187+ false
188+ ) ;
189+
190+ return llvm . Function . create (
191+ fnType ,
192+ llvm . LinkageTypes . ExternalLinkage ,
193+ mangler . getFunctionName ( < string > stmt . name . escapedText , stmt . parameters ) ,
194+ ctx . llvmModule
195+ ) ;
196+ }
197+
165198function buildFromIdentifier ( identifier : ts . Identifier , ctx : Context , builder : llvm . IRBuilder ) : llvm . Value {
166199 const variable = ctx . scope . variables . get ( < string > identifier . escapedText ) ;
167200 if ( variable ) {
@@ -183,14 +216,24 @@ function buildFromIdentifier(identifier: ts.Identifier, ctx: Context, builder: l
183216
184217 const symbolDeclaration = < ts . FunctionDeclaration > symbol . declarations [ 0 ] ;
185218 if ( symbolDeclaration . name ) {
186- const mangledFunctionName = CPPMangler . getFunctionName (
187- < string > symbolDeclaration . name . escapedText ,
188- symbolDeclaration . parameters
189- ) ;
219+ const sourceFile = symbolDeclaration . getSourceFile ( ) ;
220+
221+ if ( sourceFile . fileName === RUNTIME_DEFINITION_FILE ) {
222+ return declareFunctionFromDefinition (
223+ symbolDeclaration ,
224+ ctx ,
225+ builder ,
226+ CPPMangler
227+ ) ;
228+ }
190229
191- const fn = ctx . llvmModule . getFunction ( mangledFunctionName ) ;
192- if ( fn ) {
193- return fn ;
230+ if ( sourceFile . fileName === LANGUAGE_DEFINITION_FILE ) {
231+ return declareFunctionFromDefinition (
232+ symbolDeclaration ,
233+ ctx ,
234+ builder ,
235+ CMangler
236+ ) ;
194237 }
195238 }
196239 }
@@ -332,33 +375,16 @@ export function generateModuleFromProgram(program: ts.Program): llvm.Module {
332375 program . getTypeChecker ( )
333376 ) ;
334377
335- let putsFnType = llvm . FunctionType . get ( llvm . Type . getInt32Ty ( ctx . llvmContext ) , [
336- llvm . Type . getInt8PtrTy ( ctx . llvmContext )
337- ] , false ) ;
338- ctx . llvmModule . getOrInsertFunction ( 'puts' , putsFnType ) ;
339-
340- let number2stringFnType = llvm . FunctionType . get ( llvm . Type . getInt8PtrTy ( ctx . llvmContext ) , [
341- llvm . Type . getDoubleTy ( ctx . llvmContext )
342- ] , false ) ;
343- llvm . Function . create (
344- number2stringFnType ,
345- llvm . LinkageTypes . ExternalLinkage ,
346- CPPMangler . getFunctionName ( "number2string" , < any > [
347- {
348- type : { kind : ts . SyntaxKind . NumberKeyword }
349- }
350- ] ) ,
351- ctx . llvmModule
352- ) ;
353-
354378 let mainFnType = llvm . FunctionType . get ( llvm . Type . getVoidTy ( ctx . llvmContext ) , false ) ;
355379 let mainFn = llvm . Function . create ( mainFnType , llvm . LinkageTypes . ExternalLinkage , "main" , ctx . llvmModule ) ;
356380
357381 let block = llvm . BasicBlock . create ( ctx . llvmContext , "Entry" , mainFn ) ;
358382 let builder = new llvm . IRBuilder ( block ) ;
359383
360384 for ( const sourceFile of program . getSourceFiles ( ) ) {
361- sourceFile . forEachChild ( ( node : ts . Node ) => passNode ( node , ctx , builder ) )
385+ if ( ! sourceFile . isDeclarationFile ) {
386+ sourceFile . forEachChild ( ( node : ts . Node ) => passNode ( node , ctx , builder ) )
387+ }
362388 }
363389
364390 builder . createRetVoid ( ) ;
0 commit comments