@@ -27,6 +27,8 @@ struct LogicalExprData {
27
27
typedef struct LogicalExprData * PLogicalExprData ;
28
28
29
29
static LLVMValueRef processExpression (PSmmLLVMCodeGenData data , PSmmAstNode expr , PIbsAllocator a );
30
+ static void processBlock (PSmmLLVMCodeGenData data , PSmmAstBlockNode block , PIbsAllocator a );
31
+ static void processStatement (PSmmLLVMCodeGenData data , PSmmAstNode stmt , PIbsAllocator a );
30
32
31
33
static LLVMTypeRef getLLVMType (PSmmTypeInfo type ) {
32
34
if (!type ) return LLVMVoidType ();
@@ -296,32 +298,96 @@ static void processReturn(PSmmLLVMCodeGenData data, PSmmAstNode stmt, PIbsAlloca
296
298
} else LLVMBuildRetVoid (data -> builder );
297
299
}
298
300
301
+ static void processIf (PSmmLLVMCodeGenData data , PSmmAstIfWhileNode stmt , PIbsAllocator a ) {
302
+ LLVMBasicBlockRef trueBlock = LLVMAppendBasicBlock (data -> curFunc , "if.then" );
303
+ LLVMBasicBlockRef falseBlock ;
304
+ LLVMBasicBlockRef endBlock ;
305
+ if (stmt -> elseBody ) {
306
+ falseBlock = LLVMAppendBasicBlock (data -> curFunc , "if.else" );
307
+ endBlock = LLVMAppendBasicBlock (data -> curFunc , "if.end" );
308
+ } else {
309
+ falseBlock = LLVMAppendBasicBlock (data -> curFunc , "if.end" );
310
+ endBlock = falseBlock ;
311
+ }
312
+ LLVMValueRef res ;
313
+ data -> endBlock = trueBlock ;
314
+ if (stmt -> cond -> kind == nkSmmAndOp || stmt -> cond -> kind == nkSmmOrOp ) {
315
+ struct LogicalExprData logicalExprData = { data , data -> endBlock };
316
+ res = processAndOrInstr (& logicalExprData , stmt -> cond , trueBlock , falseBlock , a );
317
+ } else {
318
+ res = processExpression (data , stmt -> cond , a );
319
+ }
320
+ data -> endBlock = NULL ;
321
+ LLVMBuildCondBr (data -> builder , res , trueBlock , falseBlock );
322
+
323
+ LLVMPositionBuilderAtEnd (data -> builder , trueBlock );
324
+
325
+ processStatement (data , stmt -> body , a );
326
+ LLVMBuildBr (data -> builder , falseBlock );
327
+ LLVMPositionBuilderAtEnd (data -> builder , falseBlock );
328
+ if (stmt -> elseBody ) {
329
+ processStatement (data , stmt -> elseBody , a );
330
+ LLVMBuildBr (data -> builder , endBlock );
331
+ LLVMPositionBuilderAtEnd (data -> builder , endBlock );
332
+ }
333
+ }
334
+
335
+ static void processWhile (PSmmLLVMCodeGenData data , PSmmAstIfWhileNode stmt , PIbsAllocator a ) {
336
+ LLVMBasicBlockRef condBlock = LLVMAppendBasicBlock (data -> curFunc , "while.cond" );
337
+ LLVMBasicBlockRef trueBlock = LLVMAppendBasicBlock (data -> curFunc , "while.body" );
338
+ LLVMBasicBlockRef falseBlock = LLVMAppendBasicBlock (data -> curFunc , "while.end" );
339
+ LLVMBuildBr (data -> builder , condBlock );
340
+ LLVMPositionBuilderAtEnd (data -> builder , condBlock );
341
+ LLVMValueRef res ;
342
+ data -> endBlock = trueBlock ; // We initialize data.endBlock with new block
343
+ if (stmt -> cond -> kind == nkSmmAndOp || stmt -> cond -> kind == nkSmmOrOp ) {
344
+ struct LogicalExprData logicalExprData = { data , data -> endBlock };
345
+ res = processAndOrInstr (& logicalExprData , stmt -> cond , trueBlock , falseBlock , a );
346
+ } else {
347
+ res = processExpression (data , stmt -> cond , a );
348
+ }
349
+ data -> endBlock = NULL ;
350
+ LLVMBuildCondBr (data -> builder , res , trueBlock , falseBlock );
351
+
352
+ LLVMPositionBuilderAtEnd (data -> builder , trueBlock );
353
+
354
+ processStatement (data , stmt -> body , a );
355
+ LLVMBuildBr (data -> builder , condBlock );
356
+ LLVMPositionBuilderAtEnd (data -> builder , falseBlock );
357
+ }
358
+
359
+ static void processStatement (PSmmLLVMCodeGenData data , PSmmAstNode stmt , PIbsAllocator a ) {
360
+ switch (stmt -> kind ) {
361
+ case nkSmmBlock :
362
+ {
363
+ PSmmAstBlockNode newBlock = (PSmmAstBlockNode )stmt ;
364
+ processLocalSymbols (data , newBlock -> scope -> decls , a );
365
+ processBlock (data , newBlock , a );
366
+ break ;
367
+ }
368
+ case nkSmmAssignment : processAssignment (data , stmt , a ); break ;
369
+ case nkSmmIf : processIf (data , & stmt -> asIfWhile , a ); break ;
370
+ case nkSmmWhile : processWhile (data , & stmt -> asIfWhile , a ); break ;
371
+ case nkSmmDecl :
372
+ if (stmt -> left -> left -> asIdent .level == 0 ) {
373
+ LLVMTypeRef type = getLLVMType (stmt -> left -> type );
374
+ LLVMValueRef globalVar = LLVMAddGlobal (data -> llvmModule , type , stmt -> left -> left -> token -> repr );
375
+ LLVMSetGlobalConstant (globalVar , false);
376
+ LLVMSetInitializer (globalVar , processExpression (data , stmt -> left -> right , a ));
377
+ } else {
378
+ processAssignment (data , stmt -> left , a );
379
+ }
380
+ break ;
381
+ case nkSmmReturn : processReturn (data , stmt , a ); break ;
382
+ default :
383
+ processExpression (data , stmt , a ); break ;
384
+ }
385
+ }
386
+
299
387
static void processBlock (PSmmLLVMCodeGenData data , PSmmAstBlockNode block , PIbsAllocator a ) {
300
388
PSmmAstNode stmt = block -> stmts ;
301
389
while (stmt ) {
302
- switch (stmt -> kind ) {
303
- case nkSmmBlock :
304
- {
305
- PSmmAstBlockNode newBlock = (PSmmAstBlockNode )stmt ;
306
- processLocalSymbols (data , newBlock -> scope -> decls , a );
307
- processBlock (data , newBlock , a );
308
- break ;
309
- }
310
- case nkSmmAssignment : processAssignment (data , stmt , a ); break ;
311
- case nkSmmDecl :
312
- if (stmt -> left -> left -> asIdent .level == 0 ) {
313
- LLVMTypeRef type = getLLVMType (stmt -> left -> type );
314
- LLVMValueRef globalVar = LLVMAddGlobal (data -> llvmModule , type , stmt -> left -> left -> token -> repr );
315
- LLVMSetGlobalConstant (globalVar , false);
316
- LLVMSetInitializer (globalVar , processExpression (data , stmt -> left -> right , a ));
317
- } else {
318
- processAssignment (data , stmt -> left , a );
319
- }
320
- break ;
321
- case nkSmmReturn : processReturn (data , stmt , a ); break ;
322
- default :
323
- processExpression (data , stmt , a ); break ;
324
- }
390
+ processStatement (data , stmt , a );
325
391
stmt = stmt -> next ;
326
392
}
327
393
}
0 commit comments