From 1703e348189b2e81a995036383430c4180a57f7c Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 22 Apr 2025 17:32:01 +0800 Subject: [PATCH] feat:ast --- .../java/org/jcnc/snow/compiler/Main.java | 29 ++- .../snow/compiler/parser/ASTExpression.java | 8 + .../jcnc/snow/compiler/parser/ASTPrinter.java | 82 +++++++ .../snow/compiler/parser/ParserEngine.java | 201 ++++++++++++++++++ .../snow/compiler/parser/ast/ASTBinaryOp.java | 82 +++++++ .../snow/compiler/parser/ast/ASTDeclare.java | 14 ++ .../snow/compiler/parser/ast/ASTFunction.java | 19 ++ .../compiler/parser/ast/ASTIdentifier.java | 9 + .../jcnc/snow/compiler/parser/ast/ASTIf.java | 15 ++ .../snow/compiler/parser/ast/ASTLiteral.java | 9 + .../snow/compiler/parser/ast/ASTLoop.java | 19 ++ .../snow/compiler/parser/ast/ASTModule.java | 25 +++ .../snow/compiler/parser/ast/ASTNode.java | 4 + .../compiler/parser/ast/ASTParameter.java | 8 + .../snow/compiler/parser/ast/ASTReturn.java | 9 + .../compiler/parser/ast/ASTStatement.java | 3 + 16 files changed, 526 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ASTExpression.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ASTPrinter.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ParserEngine.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTBinaryOp.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTDeclare.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTFunction.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTIdentifier.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTIf.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTLiteral.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTLoop.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTModule.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTNode.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTParameter.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTReturn.java create mode 100644 src/main/java/org/jcnc/snow/compiler/parser/ast/ASTStatement.java diff --git a/src/main/java/org/jcnc/snow/compiler/Main.java b/src/main/java/org/jcnc/snow/compiler/Main.java index 2faec3c..272fbad 100644 --- a/src/main/java/org/jcnc/snow/compiler/Main.java +++ b/src/main/java/org/jcnc/snow/compiler/Main.java @@ -1,25 +1,34 @@ -// File: org/jcnc/snow/compiler/Main.java package org.jcnc.snow.compiler; - import org.jcnc.snow.compiler.lexer.LexerEngine; -import org.jcnc.snow.compiler.lexer.utils.TokenPrinter; +import org.jcnc.snow.compiler.lexer.token.Token; +import org.jcnc.snow.compiler.parser.ast.ASTModule; +import org.jcnc.snow.compiler.parser.ASTPrinter; +import org.jcnc.snow.compiler.parser.ParserEngine; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; public class Main { public static void main(String[] args) throws IOException { - // 如果命令行中提供了文件名,就读取该文件;否则默认读取当前目录下的 "opcode" 文件 + // 1. 读文件 String filePath = args.length > 0 ? args[0] : "test"; - String source = Files.readString(Path.of(filePath), StandardCharsets.UTF_8); - // 词法分析 - LexerEngine lexerEngine = new LexerEngine(source); - // 打印所有 Token - TokenPrinter.printTokens(lexerEngine.getAllTokens()); - } + // 2. 词法分析 + LexerEngine lexer = new LexerEngine(source); + List tokens = lexer.getAllTokens(); + + // 3. 语法分析 + ParserEngine parser = new ParserEngine(tokens); + ASTModule moduleAst = parser.parseModule(); + + // 4. 使用 AST + System.out.println("解析成功,模块名:" + moduleAst.getName()); + ASTPrinter.print(moduleAst); + + } } diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ASTExpression.java b/src/main/java/org/jcnc/snow/compiler/parser/ASTExpression.java new file mode 100644 index 0000000..6633459 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ASTExpression.java @@ -0,0 +1,8 @@ +package org.jcnc.snow.compiler.parser; + +/** + * 抽象的表达式节点基类,所有具体表达式都应继承此类。 + */ +public abstract class ASTExpression { + +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ASTPrinter.java b/src/main/java/org/jcnc/snow/compiler/parser/ASTPrinter.java new file mode 100644 index 0000000..03a4d97 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ASTPrinter.java @@ -0,0 +1,82 @@ +package org.jcnc.snow.compiler.parser; + +import org.jcnc.snow.compiler.parser.ast.*; + +// ----------------- AST 打印工具 ----------------- +public class ASTPrinter { + private static final String INDENT = " "; + + public static void print(ASTModule module) { + System.out.println("Module: " + module.getName()); + for (ASTFunction fn : module.getFunctions()) { + printFunction(fn, 1); + } + } + + private static void printFunction(ASTFunction fn, int level) { + String indent = INDENT.repeat(level); + System.out.println(indent + "Function: " + fn.getName() + " returns " + fn.getReturnType()); + if (!fn.getParameters().isEmpty()) { + System.out.println(indent + " Parameters:"); + for (ASTParameter p : fn.getParameters()) { + System.out.println(indent + " - " + p.getName() + ": " + p.getType()); + } + } + System.out.println(indent + " Body:"); + for (ASTStatement stmt : fn.getBody()) { + printStatement(stmt, level + 2); + } + } + + private static void printStatement(ASTStatement stmt, int level) { + String indent = INDENT.repeat(level); + if (stmt instanceof ASTReturn) { + System.out.print(indent + "Return: "); + printExpression(((ASTReturn) stmt).getExpression()); + System.out.println(); + } else if (stmt instanceof ASTDeclare) { + ASTDeclare d = (ASTDeclare) stmt; + System.out.print(indent + "Declare " + d.getName() + ": " + d.getType()); + if (d.getInitExpression() != null) { + System.out.print(" = "); printExpression(d.getInitExpression()); + } + System.out.println(); + } else if (stmt instanceof ASTLoop) { + ASTLoop loop = (ASTLoop) stmt; + System.out.println(indent + "Loop:"); + System.out.print(indent + " Init: "); printStatement(loop.getInit(), 0); + System.out.print(indent + " Condition: "); printExpression(loop.getCondition()); System.out.println(); + System.out.print(indent + " Update: "); printStatement(loop.getUpdate(), 0); + System.out.println(indent + " Body:"); + for (ASTStatement s : loop.getBody()) { + printStatement(s, level + 2); + } + } else if (stmt instanceof ASTIf) { + ASTIf ifs = (ASTIf) stmt; + System.out.print(indent + "If condition: "); printExpression(ifs.getCondition()); System.out.println(); + System.out.println(indent + " Then:"); + for (ASTStatement s : ifs.getThenStatements()) { + printStatement(s, level + 2); + } + } else { + System.out.println(indent + stmt.getClass().getSimpleName()); + } + } + + private static void printExpression(ASTExpression expr) { + if (expr instanceof ASTLiteral) { + System.out.print(((ASTLiteral) expr).getValue()); + } else if (expr instanceof ASTIdentifier) { + System.out.print(((ASTIdentifier) expr).getName()); + } else if (expr instanceof ASTBinaryOp) { + ASTBinaryOp bin = (ASTBinaryOp) expr; + System.out.print("("); + printExpression(bin.getLeft()); + System.out.print(" " + bin.getOperator() + " "); + printExpression(bin.getRight()); + System.out.print(")"); + } else { + System.out.print(expr.getClass().getSimpleName()); + } + } +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ParserEngine.java b/src/main/java/org/jcnc/snow/compiler/parser/ParserEngine.java new file mode 100644 index 0000000..a2777a4 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ParserEngine.java @@ -0,0 +1,201 @@ +package org.jcnc.snow.compiler.parser; + +import org.jcnc.snow.compiler.lexer.token.Token; +import org.jcnc.snow.compiler.lexer.token.TokenType; +import org.jcnc.snow.compiler.parser.ast.*; + +import java.util.ArrayList; +import java.util.List; + +/** + * 递归下降解析器,实现对模块、函数、语句和表达式的完整解析 + */ +public class ParserEngine { + private final List tokens; + private int pos = 0; + + public ParserEngine(List tokens) { + this.tokens = tokens; + } + + public ASTModule parseModule() { + match(TokenType.KEYWORD, "module"); + match(TokenType.COLON); + String moduleName = current().getLexeme(); + match(TokenType.IDENTIFIER); + match(TokenType.NEWLINE); + + ASTModule module = new ASTModule(moduleName); + while (!peek(TokenType.KEYWORD, "end")) { + module.addFunction(parseFunction()); + } + + match(TokenType.KEYWORD, "end"); + match(TokenType.KEYWORD, "module"); + match(TokenType.NEWLINE); + return module; + } + + private ASTFunction parseFunction() { + match(TokenType.KEYWORD, "function"); + match(TokenType.COLON); + String funcName = current().getLexeme(); + match(TokenType.IDENTIFIER); + match(TokenType.NEWLINE); + + ASTFunction fn = new ASTFunction(funcName); + if (peek(TokenType.KEYWORD, "parameter")) { + match(TokenType.KEYWORD, "parameter"); + match(TokenType.COLON); + match(TokenType.NEWLINE); + while (peek(TokenType.KEYWORD, "declare")) { + fn.addParameter(parseParameter()); + } + } + + match(TokenType.KEYWORD, "return_type"); + match(TokenType.COLON); + String returnType = current().getLexeme(); + match(TokenType.TYPE); + match(TokenType.NEWLINE); + fn.setReturnType(returnType); + + match(TokenType.KEYWORD, "body"); + match(TokenType.COLON); + match(TokenType.NEWLINE); + while (!peek(TokenType.KEYWORD, "end")) { + fn.addStatement(parseStatement()); + } + match(TokenType.KEYWORD, "end"); + match(TokenType.KEYWORD, "body"); + match(TokenType.NEWLINE); + + match(TokenType.KEYWORD, "end"); + match(TokenType.KEYWORD, "function"); + match(TokenType.NEWLINE); + return fn; + } + + private ASTParameter parseParameter() { + match(TokenType.KEYWORD, "declare"); + String name = current().getLexeme(); + match(TokenType.IDENTIFIER); + match(TokenType.COLON); + String type = current().getLexeme(); + match(TokenType.TYPE); + match(TokenType.NEWLINE); + return new ASTParameter(name, type); + } + + private ASTStatement parseStatement() { + if (peek(TokenType.KEYWORD, "return")) { + return parseReturn(); + } else if (peek(TokenType.KEYWORD, "declare")) { + return parseDeclare(); + } else if (peek(TokenType.KEYWORD, "loop")) { + return parseLoop(); + } else if (peek(TokenType.KEYWORD, "if")) { + return parseIf(); + } + throw new ASTBinaryOp.ParseException("无法识别的语句:" + current()); + } + + private ASTReturn parseReturn() { + match(TokenType.KEYWORD, "return"); + ASTExpression expr = parseExpression(); + match(TokenType.NEWLINE); + return new ASTReturn(expr); + } + + private ASTDeclare parseDeclare() { + match(TokenType.KEYWORD, "declare"); + String name = current().getLexeme(); match(TokenType.IDENTIFIER); + match(TokenType.COLON); + String type = current().getLexeme(); match(TokenType.TYPE); + if (peek(TokenType.EQUALS)) { + match(TokenType.EQUALS); + ASTExpression init = parseExpression(); + match(TokenType.NEWLINE); + return new ASTDeclare(name, type, init); + } else { + match(TokenType.NEWLINE); + return new ASTDeclare(name, type, null); + } + } + + private ASTLoop parseLoop() { + match(TokenType.KEYWORD, "loop"); match(TokenType.COLON); + match(TokenType.NEWLINE); + match(TokenType.KEYWORD, "initializer"); match(TokenType.COLON); match(TokenType.NEWLINE); + ASTDeclare init = parseDeclare(); + match(TokenType.KEYWORD, "condition"); match(TokenType.COLON); match(TokenType.NEWLINE); + ASTExpression cond = parseExpression(); match(TokenType.NEWLINE); + match(TokenType.KEYWORD, "update"); match(TokenType.COLON); match(TokenType.NEWLINE); + ASTDeclare update = parseDeclare(); + match(TokenType.KEYWORD, "body"); match(TokenType.COLON); match(TokenType.NEWLINE); + List stmts = new ArrayList<>(); + while (!peek(TokenType.KEYWORD, "end")) { + stmts.add(parseStatement()); + } + match(TokenType.KEYWORD, "end"); match(TokenType.KEYWORD, "body"); match(TokenType.NEWLINE); + match(TokenType.KEYWORD, "end"); match(TokenType.KEYWORD, "loop"); match(TokenType.NEWLINE); + return new ASTLoop(init, cond, update, stmts); + } + + private ASTIf parseIf() { + match(TokenType.KEYWORD, "if"); + ASTExpression cond = parseExpression(); + match(TokenType.KEYWORD, "then"); match(TokenType.NEWLINE); + List thenStmts = new ArrayList<>(); + while (!peek(TokenType.KEYWORD, "end")) { + thenStmts.add(parseStatement()); + } + match(TokenType.KEYWORD, "end"); match(TokenType.KEYWORD, "if"); match(TokenType.NEWLINE); + return new ASTIf(cond, thenStmts); + } + + private ASTExpression parseExpression() { + ASTExpression left; + Token t = current(); + if (t.getType() == TokenType.IDENTIFIER) { + left = new ASTIdentifier(t.getLexeme()); pos++; + } else if (t.getType() == TokenType.NUMBER_LITERAL) { + left = new ASTLiteral(Integer.parseInt(t.getLexeme())); pos++; + } else { + throw new ASTBinaryOp.ParseException("表达式解析错误,意外的令牌:" + t); + } + // 处理二元运算 + Token opTok = current(); + String lex = opTok.getLexeme(); + if (opTok.getType() == TokenType.PLUS + || opTok.getType() == TokenType.MINUS + || opTok.getType() == TokenType.MULTIPLY + || lex.equals("/")) { + String op = lex; + pos++; + ASTExpression right = parseExpression(); + return new ASTBinaryOp(left, op, right); + } + return left; + } + + // 工具方法 + private Token current() { + if (pos >= tokens.size()) throw new ASTBinaryOp.ParseException("超出令牌范围"); + return tokens.get(pos); + } + private boolean peek(TokenType type) { + return current().getType() == type; + } + private boolean peek(TokenType type, String lexeme) { + return peek(type) && current().getLexeme().equals(lexeme); + } + private void match(TokenType type) { + if (peek(type)) pos++; else throw new ASTBinaryOp.ParseException("期望 " + type + " 但找到 " + current()); + } + private void match(TokenType type, String lexeme) { + if (peek(type, lexeme)) pos++; else throw new ASTBinaryOp.ParseException("期望 '" + lexeme + "' 但找到 " + current()); + } +} + + diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTBinaryOp.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTBinaryOp.java new file mode 100644 index 0000000..f114403 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTBinaryOp.java @@ -0,0 +1,82 @@ +package org.jcnc.snow.compiler.parser.ast; + +import org.jcnc.snow.compiler.parser.ASTExpression; + +/** + * 表示一个二元运算表达式节点(例如加法、减法、乘法、除法)。 + * 在 AST 中,该节点有一个左子表达式、一个运算符和一个右子表达式。 + */ +public class ASTBinaryOp extends ASTExpression { + /** + * 左侧操作数表达式。 + */ + private final ASTExpression left; + + /** + * 运算符字符串(如 "+", "-", "*", "/")。 + */ + private final String op; + + /** + * 右侧操作数表达式。 + */ + private final ASTExpression right; + + /** + * 构造一个二元运算节点。 + * + * @param left 左侧子表达式,不得为 {@code null} + * @param op 运算符文本,例如 "+"、"-"、"*"、"/" + * @param right 右侧子表达式,不得为 {@code null} + * @throws IllegalArgumentException 如果 {@code left} 或 {@code right} 为 {@code null} + */ + public ASTBinaryOp(ASTExpression left, String op, ASTExpression right) { + if (left == null || right == null) { + throw new IllegalArgumentException("左右表达式都必须非空"); + } + this.left = left; + this.op = op; + this.right = right; + } + + /** + * 获取左侧子表达式。 + * + * @return 左侧的 {@link ASTExpression} 节点 + */ + public ASTExpression getLeft() { + return left; + } + + /** + * 获取二元运算符。 + * + * @return 运算符字符串,如 "+"、"-" 等 + */ + public String getOperator() { + return op; + } + + /** + * 获取右侧子表达式。 + * + * @return 右侧的 {@link ASTExpression} 节点 + */ + public ASTExpression getRight() { + return right; + } + + /** + * 在解析过程中遇到语法错误时抛出此异常。 + */ + public static class ParseException extends RuntimeException { + /** + * 使用指定的错误消息构造一个解析异常。 + * + * @param msg 错误描述 + */ + public ParseException(String msg) { + super(msg); + } + } +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTDeclare.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTDeclare.java new file mode 100644 index 0000000..0134660 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTDeclare.java @@ -0,0 +1,14 @@ +package org.jcnc.snow.compiler.parser.ast; + +import org.jcnc.snow.compiler.parser.ASTExpression; + +public class ASTDeclare extends ASTStatement { + final String name, type; + final ASTExpression init; + public ASTDeclare(String name, String type, ASTExpression init) { + this.name = name; this.type = type; this.init = init; + } + public String getName() { return name; } + public String getType() { return type; } + public ASTExpression getInitExpression() { return init; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTFunction.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTFunction.java new file mode 100644 index 0000000..1ba07c5 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTFunction.java @@ -0,0 +1,19 @@ +package org.jcnc.snow.compiler.parser.ast; + +import java.util.ArrayList; +import java.util.List; + +public class ASTFunction extends ASTNode { + private final String name; + private String returnType; + private final List params = new ArrayList<>(); + private final List body = new ArrayList<>(); + public ASTFunction(String name) { this.name = name; } + public void addParameter(ASTParameter p) { params.add(p); } + public void setReturnType(String t) { this.returnType = t; } + public void addStatement(ASTStatement stmt) { body.add(stmt); } + public String getName() { return name; } + public String getReturnType() { return returnType; } + public List getParameters() { return params; } + public List getBody() { return body; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTIdentifier.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTIdentifier.java new file mode 100644 index 0000000..f0ce4d9 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTIdentifier.java @@ -0,0 +1,9 @@ +package org.jcnc.snow.compiler.parser.ast; + +import org.jcnc.snow.compiler.parser.ASTExpression; + +public class ASTIdentifier extends ASTExpression { + final String name; + public ASTIdentifier(String name) { this.name = name; } + public String getName() { return name; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTIf.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTIf.java new file mode 100644 index 0000000..68e6a88 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTIf.java @@ -0,0 +1,15 @@ +package org.jcnc.snow.compiler.parser.ast; + +import org.jcnc.snow.compiler.parser.ASTExpression; + +import java.util.List; + +public class ASTIf extends ASTStatement { + final ASTExpression condition; + final List thenStmts; + public ASTIf(ASTExpression condition, List thenStmts) { + this.condition = condition; this.thenStmts = thenStmts; + } + public ASTExpression getCondition() { return condition; } + public List getThenStatements() { return thenStmts; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTLiteral.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTLiteral.java new file mode 100644 index 0000000..2074465 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTLiteral.java @@ -0,0 +1,9 @@ +package org.jcnc.snow.compiler.parser.ast; + +import org.jcnc.snow.compiler.parser.ASTExpression; + +public class ASTLiteral extends ASTExpression { + final int value; + public ASTLiteral(int value) { this.value = value; } + public int getValue() { return value; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTLoop.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTLoop.java new file mode 100644 index 0000000..1a73edf --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTLoop.java @@ -0,0 +1,19 @@ +package org.jcnc.snow.compiler.parser.ast; + +import org.jcnc.snow.compiler.parser.ASTExpression; + +import java.util.List; + +public class ASTLoop extends ASTStatement { + final ASTDeclare init; + final ASTExpression condition; + final ASTDeclare update; + final List body; + public ASTLoop(ASTDeclare init, ASTExpression condition, ASTDeclare update, List body) { + this.init = init; this.condition = condition; this.update = update; this.body = body; + } + public ASTDeclare getInit() { return init; } + public ASTExpression getCondition() { return condition; } + public ASTDeclare getUpdate() { return update; } + public List getBody() { return body; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTModule.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTModule.java new file mode 100644 index 0000000..f6173e6 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTModule.java @@ -0,0 +1,25 @@ +package org.jcnc.snow.compiler.parser.ast; + +import java.util.ArrayList; +import java.util.List; + +public class ASTModule extends ASTNode { + private final String name; + private final List functions = new ArrayList<>(); + + public ASTModule(String name) { + this.name = name; + } + + public void addFunction(ASTFunction fn) { + functions.add(fn); + } + + public String getName() { + return name; + } + + public List getFunctions() { + return functions; + } +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTNode.java new file mode 100644 index 0000000..1fe49bd --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTNode.java @@ -0,0 +1,4 @@ +package org.jcnc.snow.compiler.parser.ast; + +// ----------------- AST 节点定义 ----------------- +public abstract class ASTNode {} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTParameter.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTParameter.java new file mode 100644 index 0000000..3b576eb --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTParameter.java @@ -0,0 +1,8 @@ +package org.jcnc.snow.compiler.parser.ast; + +public class ASTParameter extends ASTNode { + final String name, type; + public ASTParameter(String name, String type) { this.name = name; this.type = type; } + public String getName() { return name; } + public String getType() { return type; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTReturn.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTReturn.java new file mode 100644 index 0000000..edc1902 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTReturn.java @@ -0,0 +1,9 @@ +package org.jcnc.snow.compiler.parser.ast; + +import org.jcnc.snow.compiler.parser.ASTExpression; + +class ASTReturn extends ASTStatement { + final ASTExpression expr; + public ASTReturn(ASTExpression expr) { this.expr = expr; } + public ASTExpression getExpression() { return expr; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTStatement.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTStatement.java new file mode 100644 index 0000000..731a5c2 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ASTStatement.java @@ -0,0 +1,3 @@ +package org.jcnc.snow.compiler.parser.ast; + +abstract class ASTStatement extends ASTNode {}