Skip to content

Commit

Permalink
Added /, *, and % operator on binary expression AST.
Browse files Browse the repository at this point in the history
  • Loading branch information
nthnn committed Apr 27, 2024
1 parent 388de7d commit ae4c8f9
Showing 1 changed file with 173 additions and 12 deletions.
185 changes: 173 additions & 12 deletions core/ast/expr/expr_binary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ export default class ExprASTBinary implements ExpressionAST {
const rightType: DataType =
this.right.type();

if(DataType.isOfIntType(leftType) &&
DataType.isOfIntType(rightType))
if((DataType.isOfIntType(leftType) || DataType.isOfUIntType(leftType)) &&
(DataType.isOfIntType(rightType) || DataType.isOfUIntType(rightType)))
return builder.CreateIntCast(
builder.CreateAdd(
this.left.visit(builder, module),
Expand All @@ -45,7 +45,7 @@ export default class ExprASTBinary implements ExpressionAST {
).getLLVMType(),
true
);
else if(DataType.isOfIntType(leftType) &&
else if((DataType.isOfIntType(leftType) || DataType.isOfUIntType(leftType)) &&
DataType.isOfFloatType(rightType)) {
const outputType: Type =
rightType.getLLVMType();
Expand Down Expand Up @@ -74,7 +74,7 @@ export default class ExprASTBinary implements ExpressionAST {
).getLLVMType()
);
else if(DataType.isOfFloatType(leftType) &&
DataType.isOfIntType(rightType)) {
(DataType.isOfIntType(rightType) || DataType.isOfUIntType(rightType))) {
const outputType: Type =
leftType.getLLVMType();

Expand Down Expand Up @@ -119,7 +119,7 @@ export default class ExprASTBinary implements ExpressionAST {
]
);
}
else if(DataType.isOfIntType(leftType) &&
else if((DataType.isOfIntType(leftType) || DataType.isOfUIntType(leftType)) &&
rightType == DataType.STRING)
return builder.CreateCall(
YttriaRuntime.concatStrStr(module),
Expand All @@ -138,7 +138,7 @@ export default class ExprASTBinary implements ExpressionAST {
]
);
else if(leftType == DataType.STRING &&
DataType.isOfIntType(rightType))
(DataType.isOfIntType(rightType) || DataType.isOfUIntType(rightType)))
return builder.CreateCall(
YttriaRuntime.concatStrStr(module),
[
Expand Down Expand Up @@ -192,7 +192,8 @@ export default class ExprASTBinary implements ExpressionAST {
]
);

throw new ASTError('Invalid operation.');
throw new ASTError('Invalid binary operation [' +
leftType.toString() + '+' + rightType.toString() + ']');
}

private visitSub(
Expand All @@ -204,13 +205,13 @@ export default class ExprASTBinary implements ExpressionAST {
const rightType: DataType =
this.right.type();

if(DataType.isOfIntType(leftType) &&
DataType.isOfIntType(rightType))
if((DataType.isOfIntType(leftType) || DataType.isOfUIntType(leftType)) &&
(DataType.isOfIntType(rightType) || DataType.isOfUIntType(rightType)))
return builder.CreateSub(
this.left.visit(builder, module),
this.right.visit(builder, module)
);
else if(DataType.isOfIntType(leftType) &&
else if((DataType.isOfIntType(leftType) || DataType.isOfUIntType(leftType)) &&
DataType.isOfFloatType(rightType))
return builder.CreateFSub(
builder.CreateFPCast(
Expand All @@ -226,7 +227,7 @@ export default class ExprASTBinary implements ExpressionAST {
this.right.visit(builder, module)
);
else if(DataType.isOfFloatType(leftType) &&
DataType.isOfIntType(rightType))
(DataType.isOfIntType(rightType) || DataType.isOfUIntType(rightType)))
return builder.CreateFSub(
this.left.visit(builder, module),
builder.CreateFPCast(
Expand All @@ -235,7 +236,152 @@ export default class ExprASTBinary implements ExpressionAST {
)
);

throw new ASTError('Invalid operation.');
throw new ASTError('Invalid binary operation [' +
leftType.toString() + '-' + rightType.toString() + ']');
}

private visitDiv(
builder: IRBuilder,
module: Module
): Value {
const leftType: DataType =
this.left.type();
const rightType: DataType =
this.right.type();

if(DataType.isOfIntType(leftType) &&
DataType.isOfIntType(rightType))
return builder.CreateSDiv(
this.left.visit(builder, module),
this.right.visit(builder, module)
);
else if(DataType.isOfUIntType(leftType) &&
DataType.isOfUIntType(rightType))
return builder.CreateUDiv(
this.left.visit(builder, module),
this.right.visit(builder, module)
);
else if((DataType.isOfIntType(leftType) || DataType.isOfUIntType(leftType)) &&
DataType.isOfFloatType(rightType))
return builder.CreateFDiv(
builder.CreateFPCast(
this.left.visit(builder, module),
rightType.getLLVMType()
),
this.right.visit(builder, module)
);
else if(DataType.isOfFloatType(leftType) &&
DataType.isOfFloatType(rightType))
return builder.CreateFDiv(
this.left.visit(builder, module),
this.right.visit(builder, module)
);
else if(DataType.isOfFloatType(leftType) &&
(DataType.isOfIntType(rightType) || DataType.isOfUIntType(rightType)))
return builder.CreateFDiv(
this.left.visit(builder, module),
builder.CreateFPCast(
this.right.visit(builder, module),
rightType.getLLVMType()
)
);

throw new ASTError('Invalid binary operation [' +
leftType.toString() + '/' + rightType.toString() + ']');
}

private visitMul(
builder: IRBuilder,
module: Module
): Value {
const leftType: DataType =
this.left.type();
const rightType: DataType =
this.right.type();

if((DataType.isOfIntType(leftType) || DataType.isOfUIntType(leftType)) &&
(DataType.isOfIntType(rightType) || DataType.isOfUIntType(rightType)))
return builder.CreateMul(
this.left.visit(builder, module),
this.right.visit(builder, module)
);
else if((DataType.isOfIntType(leftType) || DataType.isOfUIntType(leftType)) &&
DataType.isOfFloatType(rightType))
return builder.CreateFMul(
builder.CreateFPCast(
this.left.visit(builder, module),
rightType.getLLVMType()
),
this.right.visit(builder, module)
);
else if(DataType.isOfFloatType(leftType) &&
DataType.isOfFloatType(rightType))
return builder.CreateFMul(
this.left.visit(builder, module),
this.right.visit(builder, module)
);
else if(DataType.isOfFloatType(leftType) &&
(DataType.isOfIntType(rightType) || DataType.isOfUIntType(rightType)))
return builder.CreateFMul(
this.left.visit(builder, module),
builder.CreateFPCast(
this.right.visit(builder, module),
rightType.getLLVMType()
)
);

throw new ASTError('Invalid binary operation [' +
leftType.toString() + '*' + rightType.toString() + ']');
}

private visitRem(
builder: IRBuilder,
module: Module
): Value {
const leftType: DataType =
this.left.type();
const rightType: DataType =
this.right.type();

if(DataType.isOfIntType(leftType) &&
DataType.isOfIntType(rightType))
return builder.CreateSRem(
this.left.visit(builder, module),
this.right.visit(builder, module)
);
else if(DataType.isOfUIntType(leftType) &&
DataType.isOfUIntType(rightType))
return builder.CreateURem(
this.left.visit(builder, module),
this.right.visit(builder, module)
);
else if((DataType.isOfIntType(leftType) || DataType.isOfUIntType(leftType)) &&
DataType.isOfFloatType(rightType))
return builder.CreateFRem(
builder.CreateFPCast(
this.left.visit(builder, module),
rightType.getLLVMType()
),
this.right.visit(builder, module)
);
else if(DataType.isOfFloatType(leftType) &&
DataType.isOfFloatType(rightType))
return builder.CreateFRem(
this.left.visit(builder, module),
this.right.visit(builder, module)
);
else if(DataType.isOfFloatType(leftType) &&
(DataType.isOfIntType(rightType) || DataType.isOfUIntType(rightType)))
return builder.CreateFRem(
this.left.visit(builder, module),
builder.CreateFPCast(
this.right.visit(builder, module),
rightType.getLLVMType()
)
);

throw new ASTError('Invalid binary operation [' +
leftType.toString() + '%' + rightType.toString() + ']');
}

public visit(
Expand All @@ -252,6 +398,21 @@ export default class ExprASTBinary implements ExpressionAST {
builder,
module
);
else if(this.operator == '/')
return this.visitDiv(
builder,
module
);
else if(this.operator == '*')
return this.visitDiv(
builder,
module
);
else if(this.operator == '%')
return this.visitRem(
builder,
module
);

throw new ASTError('Invalid operation.');
}
Expand Down

0 comments on commit ae4c8f9

Please sign in to comment.