Skip to content

Commit

Permalink
[#654] minor: finished try and finally code generation
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzholzbauer committed Aug 28, 2024
1 parent 6480aa3 commit 191c158
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 23 deletions.
4 changes: 2 additions & 2 deletions .run/kipper run.run.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="kipper run" type="NodeJSConfigurationType" application-parameters="run -s &quot;&quot;" path-to-js-file="./kipper/cli/bin/run" working-dir="$PROJECT_DIR$/">
<configuration default="false" name="kipper run" type="NodeJSConfigurationType" application-parameters="run --target=ts test/kipper-files/trycatch.kip" path-to-js-file="./kipper/cli/bin/run" working-dir="$PROJECT_DIR$/">
<method v="2" />
</configuration>
</component>
</component>
13 changes: 13 additions & 0 deletions kipper/core/src/compiler/ast/ast-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import type {
ClassMethodDeclarationContext,
ClassConstructorDeclarationContext,
TypeofExpressionContext,
TryCatchStatementContext,
} from "../lexer-parser";
import type { KipperProgramContext } from "../program-ctx";
import type { CompilableASTNode } from "./compilable-ast-node";
Expand Down Expand Up @@ -1001,6 +1002,18 @@ export class KipperFileASTGenerator implements KipperParserListener, ParseTreeLi
*/
public exitJumpStatement: (ctx: JumpStatementContext) => void = this.handleExitingTreeNode;

/**
* Enter a parse tree produced by `KipperParser.tryCatchStatement`.
* @param ctx The parse tree (instance of {@link KipperParserRuleContext}).
*/
public enterTryCatchStatement: (ctx: TryCatchStatementContext) => void = this.handleEnteringTreeNode;

/**
* Exit a parse tree produced by `KipperParser.tryCatchStatement`.
* @param ctx The parse tree (instance of {@link KipperParserRuleContext}).
*/
public exitTryCatchStatement: (ctx: TryCatchStatementContext) => void = this.handleExitingTreeNode;

// -------------------------------------------------------------------------------------------------------------------
// Declaration section
// -------------------------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ export interface TryCatchStatementSemantics extends SemanticData {

/**
* The catch clause that handles exceptions thrown in the try block.
* It can be either a single {@link CatchClause} or an array of them.
* It can be either a single {@link CatchBlock} or an array of them.
* @since 0.12.0
*/
catchBlock: CatchClause[];
catchBlock: CatchBlock[];

/**
* The optional finally block which is executed after the try and catch blocks, regardless of the outcome.
Expand All @@ -28,10 +28,10 @@ export interface TryCatchStatementSemantics extends SemanticData {
}

/**
* Semantics for AST Node {@link CatchClause}.
* Semantics for AST Node {@link CatchBlock}.
* @since 0.12.0
*/
export interface CatchClause extends SemanticData {
export interface CatchBlock extends SemanticData {
/**
* The variable that holds the exception thrown in the try block.
* @since 0.12.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Statement } from "../statement";
import type { Expression } from "../../expressions";
import type { CompilableNodeParent } from "../../../compilable-ast-node";
import type { TryCatchStatementTypeSemantics } from "./try-catch-statement-type-semantics";
import type { TryCatchStatementSemantics } from "./try-catch-statement-semantics";
import type { CatchBlock, TryCatchStatementSemantics } from "./try-catch-statement-semantics";

/**
* TryCatchStatement class, which represents try-catch statements in the Kipper language and is compilable using
Expand Down Expand Up @@ -92,7 +92,27 @@ export class TryCatchStatement extends Statement<TryCatchStatementSemantics, Try
* This will not run in case that {@link this.hasFailed} is true, as that indicates that the semantic analysis of
* the children has already failed and as such no parent node should run type checking.
*/
public async primarySemanticAnalysis(): Promise<void> {}
public async primarySemanticAnalysis(): Promise<void> {
const tryBlock: Statement = <Statement>this._children[0];
const catchClausesWithFinally: Array<CatchBlock | Statement> = <Array<CatchBlock | Statement>>(
this._children.slice(1)
);
let catchClauses: CatchBlock[] = [];
let finallyBlock: Statement | undefined = undefined;

if (catchClausesWithFinally[catchClausesWithFinally.length - 1] instanceof Statement) {
finallyBlock = <Statement>catchClausesWithFinally.pop();
catchClauses = <CatchBlock[]>catchClausesWithFinally;
} else {
catchClauses = <CatchBlock[]>catchClausesWithFinally;
}

this.semanticData = {
tryBlock: tryBlock,
catchBlock: catchClauses,
finallyBlock: finallyBlock,
};
}

/**
* Performs type checking for this AST Node. This will log all warnings using {@link programCtx.logger}
Expand All @@ -102,7 +122,7 @@ export class TryCatchStatement extends Statement<TryCatchStatementSemantics, Try
* the children has already failed and as such no parent node should run type checking.
* @since 0.12.0
*/
public primarySemanticTypeChecking = undefined; // If-statements will never have type checking
public primarySemanticTypeChecking = undefined; // Try-Catch-statements will never have type checking

/**
* Semantically analyses the code inside this AST node and checks for possible warnings or problematic code.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const ParseRuleKindMapping = {
RULE_doWhileLoopIterationStatement: KipperParser.RULE_doWhileLoopIterationStatement,
RULE_jumpStatement: KipperParser.RULE_jumpStatement,
RULE_returnStatement: KipperParser.RULE_returnStatement,
RULE_tryCatchStatement: KipperParser.RULE_tryCatchStatement,
RULE_primaryExpression: KipperParser.RULE_primaryExpression,
RULE_lambdaPrimaryExpression: KipperParser.RULE_lambdaPrimaryExpression,
RULE_tangledPrimaryExpression: KipperParser.RULE_tangledPrimaryExpression,
Expand Down Expand Up @@ -104,7 +105,6 @@ export const ParseRuleKindMapping = {
RULE_genericTypeSpecifierExpression: KipperParser.RULE_genericTypeSpecifierExpression,
RULE_typeofTypeSpecifierExpression: KipperParser.RULE_typeofTypeSpecifierExpression,
RULE_typeSpecifierIdentifier: KipperParser.RULE_typeSpecifierIdentifier,
RULE_tryCatchStatement: KipperParser.RULE_tryCatchStatement,
// Labelled rules, which don't have a corresponding identifier number in KipperParser.
RULE_memberAccessExpression: 1001, // -> See 'computedPrimaryExpression'
RULE_functionCallExpression: 1002, // -> See 'computedPrimaryExpression'
Expand Down
19 changes: 10 additions & 9 deletions kipper/target-js/src/code-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import type {
BitwiseXorExpression,
BoolPrimaryExpression,
CastOrConvertExpression,
CatchClause,
ClassConstructorDeclaration,
ClassDeclaration,
ClassMethodDeclaration,
Expand Down Expand Up @@ -482,20 +481,22 @@ export class JavaScriptTargetCodeGenerator extends KipperTargetCodeGenerator {
tryCatchStatement = async (node: TryCatchStatement): Promise<Array<TranslatedCodeLine>> => {
const semanticData = node.getSemanticData();
const tryBlock = await semanticData.tryBlock.translateCtxAndChildren();
const catchBlock = await Promise.all(
semanticData.catchBlock.map(async (catchClause) => {
const parameter = catchClause.getSemanticData().parameter;
const body = await catchClause.getSemanticData().body.translateCtxAndChildren();
return [["catch", " ", "(", parameter, ")", " ", "{"], ...indentLines(body), ["}"]];
const catchBlocks = <TranslatedCodeLine[][]>await Promise.all(
semanticData.catchBlock.map(async (block) => {
const parameter = await block.parameter.translateCtxAndChildren();
const body = await block.body
.translateCtxAndChildren()
.then((body) => (block.body instanceof CompoundStatement ? removeBrackets(body) : indentLines(body)));
return ["catch", " ", "(", ...parameter, ")", " ", "{", ...body, "}"];
}),
);
const finallyBlock = semanticData.finallyBlock ? await semanticData.finallyBlock.translateCtxAndChildren() : [];

return [
["try", " ", "{"],
["try"],
...indentLines(tryBlock),
...catchBlock.flat(),
...(finallyBlock.length > 0 ? [["finally", " ", "{"], ...indentLines(finallyBlock), ["}"]] : []),
...catchBlocks.flat(),
...(finallyBlock.length > 0 ? [["finally"], ...indentLines(finallyBlock)] : []),
];
};

Expand Down
13 changes: 9 additions & 4 deletions test/kipper-files/trycatch.kip
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ interface Exception {
a: str;
b: num;
}

var x: num = 1;
try{
var x: num = 3;
x = 2;
}
catch(e: Exception){

catch(e: Exception) {
x = 3;
}
finally {
x = 4;
}

print(x);

0 comments on commit 191c158

Please sign in to comment.