Skip to content

Commit

Permalink
fully implemented try-catch statements and throw statements
Browse files Browse the repository at this point in the history
  • Loading branch information
aName2050 committed Mar 28, 2024
1 parent 91023bd commit 4266293
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/GigaScript/ast/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type ASTNodeType =
| 'FunctionDeclaration'
| 'ReturnStatement'
| 'TryCatchStatement'
| 'ThrowStatement'
| 'CodeBlockNode'
| 'EOF'
// Expressions
Expand Down
5 changes: 5 additions & 0 deletions src/GigaScript/ast/statements.ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ export interface TryCatchStatement extends STATEMENT {
catchBody: CodeBlockNode;
errorIdentifier: string;
}

export interface ThrowStatement extends STATEMENT {
kind: 'ThrowStatement';
message: EXPRESSION;
}
21 changes: 20 additions & 1 deletion src/GigaScript/parser/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import {
Property,
StringLiteral,
} from '../ast/literals.ast';
import { ReturnStatement, TryCatchStatement } from '../ast/statements.ast';
import {
ReturnStatement,
ThrowStatement,
TryCatchStatement,
} from '../ast/statements.ast';
import { tokenize } from '../lexer/tokenizer';
import { NodeType } from '../nodes';
import { Token, getTokenByTypeEnum } from '../tokens';
Expand Down Expand Up @@ -144,6 +148,9 @@ export default class Parser {
case NodeType.Return:
return this.parseReturnStatement();

case NodeType.Throw:
return this.parseThrowStatement();

default:
return this.parseExpr();
}
Expand Down Expand Up @@ -293,6 +300,18 @@ export default class Parser {
} as ReturnStatement;
}

private parseThrowStatement(): STATEMENT {
const throwTokenPos = this.advance().__GSC._POS;
const message = this.parseExpr();

return {
kind: 'ThrowStatement',
message,
start: throwTokenPos.start,
end: message.end,
} as ThrowStatement;
}

// [FUNCTIONS.ARGUMENTS/PARAMETERS]
private parseArgs(): Array<EXPRESSION> {
this.expect(NodeType.OpenParen, 'before parameter list');
Expand Down
55 changes: 53 additions & 2 deletions src/GigaScript/runtime/interpreter/eval/statements.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { Program } from '../../../ast/ast';
import { CodeBlockNode, Program } from '../../../ast/ast';
import {
FunctionDeclaration,
VariableDeclaration,
} from '../../../ast/declarations.ast';
import { ReturnStatement } from '../../../ast/statements.ast';
import {
ReturnStatement,
ThrowStatement,
TryCatchStatement,
} from '../../../ast/statements.ast';
import Environment from '../../env';
import { DataConstructors, DataType, FuncVal, Value } from '../../types';
import { evaluate } from '../interpreter';
Expand Down Expand Up @@ -55,3 +59,50 @@ export function evalReturnStatement(

return value;
}

export function evalTryCatchStatement(
statement: TryCatchStatement,
env: Environment
): Value<DataType, any> {
const tryEnv = new Environment(env.cwd, env);
const catchEnv = new Environment(env.cwd, env);

try {
return evalCodeBlock(statement.tryBody, tryEnv, false);
} catch (e) {
catchEnv.delcareVar(
statement.errorIdentifier,
DataConstructors.STRING(String(e)),
true
);
return evalCodeBlock(statement.catchBody, catchEnv, false);
}
}

export function evalThrowStatement(
statement: ThrowStatement,
env: Environment
): Value<'null', null> {
const message = evaluate(statement.message, env);

throw message.value;
}

export function evalCodeBlock(
body: CodeBlockNode,
env: Environment,
createNewEnv = true
): Value<DataType, any> {
let scope: Environment;

if (createNewEnv) scope = new Environment(env.cwd, env);
else scope = env;

let res: Value<DataType, any> = DataConstructors.NULL();

for (const stmt of body.body) {
res = evaluate(stmt, scope);
}

return res;
}
14 changes: 13 additions & 1 deletion src/GigaScript/runtime/interpreter/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import {
ObjectLiteral,
StringLiteral,
} from '../../ast/literals.ast';
import { ReturnStatement } from '../../ast/statements.ast';
import {
ReturnStatement,
ThrowStatement,
TryCatchStatement,
} from '../../ast/statements.ast';
import { GSError } from '../../util/gserror';
import Environment from '../env';
import { DataType, Value } from '../types';
Expand All @@ -30,6 +34,8 @@ import {
evalProgram,
evalReturnStatement,
evalVarDeclaration,
evalTryCatchStatement,
evalThrowStatement,
} from './eval/statements';

export function evaluate(
Expand Down Expand Up @@ -93,6 +99,12 @@ export function evaluate(
case 'ReturnStatement':
return evalReturnStatement(node as ReturnStatement, env);

case 'TryCatchStatement':
return evalTryCatchStatement(node as TryCatchStatement, env);

case 'ThrowStatement':
return evalThrowStatement(node as ThrowStatement, env);

// Handle non implemented types
default:
console.log(
Expand Down
2 changes: 2 additions & 0 deletions tests/main.g
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ print(obj.complex.foo)

try {
print("hello world!")
throw 'test'
} catch (e) {
print('an error was caught!')
print(e)
}

0 comments on commit 4266293

Please sign in to comment.