Skip to content

Commit

Permalink
Implemented binary & and | operator AST.
Browse files Browse the repository at this point in the history
  • Loading branch information
nthnn committed Aug 18, 2023
1 parent 277e347 commit 53a3904
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 3 deletions.
89 changes: 89 additions & 0 deletions src/ast_expr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,97 @@ class ExprASTEquality implements ExpressionAST {
}
}

class ExprASTBinary implements ExpressionAST {
private mark: Token;
private operator: string;
private left: ExpressionAST;
private right: ExpressionAST;

public constructor(
mark: Token,
operator: string,
left: ExpressionAST,
right: ExpressionAST
) {
this.mark = mark;
this.operator = operator;
this.left = left;
this.right = right;
}

public visit(
builder: IRBuilder,
module: Module
): Constant {
const leftExpr: Constant =
this.left.visit(builder, module);
const rightExpr: Constant =
this.right.visit(builder, module);
const outType: Type =
DataType.greaterIntegerType(
this.left.type(),
this.right.type()
).getLLVMType();

if(this.operator == '|')
return builder.CreateIntCast(
builder.CreateOr(
leftExpr,
rightExpr
),
outType,
true
) as Constant;
else if(this.operator == '&')
return builder.CreateIntCast(
builder.CreateAnd(
leftExpr,
rightExpr
),
outType,
true
) as Constant;

throw new ASTError('Invalid binary operator.');
}

public type(): DataType {
return DataType.greaterIntegerType(
this. left.type(),
this.right.type()
);
}

public resolve(
results: ASTResolveResults
): void {
if(!DataType.isOfIntType(this.left.type()))
results.errors.set(
this.left.marker(),
'Left-hand of binary operation' +
' is not of integer type.'
);

if(!DataType.isOfIntType(this.right.type()))
results.errors.set(
this.right.marker(),
'Right-hand of binary operation' +
' is not of integer type.'
);


this.left.resolve(results);
this.right.resolve(results);
}

public marker(): Token {
return this.mark;
}
}

export {
ExprASTBool,
ExprASTBinary,
ExprASTEquality,
ExprASTString,
ExprASTInt,
Expand Down
23 changes: 23 additions & 0 deletions src/data_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,29 @@ class DataType {
public static F64: DataType =
new DataType("f64", 64, Type.getDoubleTy(LLVMGlobalContext));

public static greaterIntegerType(
a: DataType,
b: DataType
): DataType {
if(a == b)
return a;

switch(a) {
case DataType.I4:
return b;
case DataType.I8:
return (b == DataType.I4) ?
a : b;
case DataType.I16:
return (b == DataType.I64) ?
b : a;
case DataType.I64:
return a;
}

return b;
}

public static isOfIntType(
type: DataType
): boolean {
Expand Down
7 changes: 4 additions & 3 deletions src/yttria.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from './tokenizer';

import {
ExprASTBinary,
ExprASTBool,
ExprASTEquality,
ExprASTFloat,
Expand Down Expand Up @@ -65,9 +66,9 @@ function llvmTest() {
LLVMGlobalContext
);

const expr1: ExprASTString = new ExprASTString(nullToken, 'hi');
const expr2: ExprASTString = new ExprASTString(nullToken, 'hi');
const cmp: ExprASTEquality = new ExprASTEquality(nullToken, '==', expr1, expr2);
const expr1: ExprASTInt = new ExprASTInt(nullToken, BigInt('101'), 32);
const expr2: ExprASTInt = new ExprASTInt(nullToken, BigInt('99'), 32);
const cmp: ExprASTBinary = new ExprASTBinary(nullToken, '&', expr1, expr2);
const body: StmtASTRender = new StmtASTRender(nullToken, cmp);
const main: StmtASTMain = new StmtASTMain(nullToken, body);

Expand Down

0 comments on commit 53a3904

Please sign in to comment.