Added function call and function definition
This commit is contained in:
@@ -1,11 +1,19 @@
|
||||
grammar Klang;
|
||||
|
||||
parse
|
||||
: block <EOF>
|
||||
: program <EOF>
|
||||
;
|
||||
|
||||
block
|
||||
: statement+
|
||||
program
|
||||
: functionDef* expression
|
||||
;
|
||||
|
||||
functionDef
|
||||
: FUNC funcName=IDENT OPAR parameters CPAR braced_block
|
||||
;
|
||||
|
||||
parameters
|
||||
: (IDENT (COMMA IDENT)*)?
|
||||
;
|
||||
|
||||
braced_block
|
||||
@@ -31,6 +39,15 @@ expression
|
||||
| atom MOD atom #moduloExpression
|
||||
| SUB atom #unaryNegateExpression
|
||||
| atom #atomExpression
|
||||
| functionCall #functionCallExpression
|
||||
;
|
||||
|
||||
functionCall
|
||||
: IDENT OPAR arguments CPAR SCOL
|
||||
;
|
||||
|
||||
arguments
|
||||
: (expression (COMMA expression)*)?
|
||||
;
|
||||
|
||||
atom
|
||||
@@ -40,12 +57,14 @@ atom
|
||||
PRINT: 'print';
|
||||
IF: 'if';
|
||||
ELSE: 'else';
|
||||
FUNC: 'function';
|
||||
|
||||
SCOL: ';';
|
||||
OBRK: '{';
|
||||
CBRK: '}';
|
||||
OPAR: '(';
|
||||
CPAR: ')';
|
||||
COMMA: ',';
|
||||
|
||||
MULT: '*';
|
||||
ADD: '+';
|
||||
@@ -56,6 +75,10 @@ INTEGER_LITERAL
|
||||
: [0-9]+
|
||||
;
|
||||
|
||||
IDENT
|
||||
: [a-zA-Z][a-zA-Z0-9]*
|
||||
;
|
||||
|
||||
WS
|
||||
: [ \t\r\n] -> skip
|
||||
;
|
||||
|
||||
@@ -7,17 +7,13 @@ import de.hsrm.compiler.Klang.types.Type;
|
||||
|
||||
public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
@Override
|
||||
public Node visitBlock(KlangParser.BlockContext ctx) {
|
||||
Statement[] statements = new Statement[ctx.statement().size()];
|
||||
|
||||
for (int i = 0; i < ctx.statement().size(); i++) {
|
||||
Node currentStatement = this.visit(ctx.statement(i));
|
||||
statements[i] = (Statement) currentStatement;
|
||||
public Node visitProgram(KlangParser.ProgramContext ctx) {
|
||||
FunctionDefinition[] funcs = new FunctionDefinition[ctx.functionDef().size()];
|
||||
for (int i = 0; i < ctx.functionDef().size(); i++) {
|
||||
funcs[i] = (FunctionDefinition) this.visit(ctx.functionDef(i));
|
||||
}
|
||||
|
||||
Block result = new Block(statements);
|
||||
result.type = null;
|
||||
return result;
|
||||
Expression expression = (Expression) this.visit(ctx.expression());
|
||||
return new Program(funcs, expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,4 +98,25 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
n.type = Type.getIntegerType();
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node visitFunctionDef(KlangParser.FunctionDefContext ctx) {
|
||||
String name = ctx.funcName.getText();
|
||||
String[] params = new String[ctx.parameters().IDENT().size()];
|
||||
for (int i = 0; i < ctx.parameters().IDENT().size(); i++) {
|
||||
params[i] = ctx.parameters().IDENT(i).getText();
|
||||
}
|
||||
Node block = this.visit(ctx.braced_block());
|
||||
return new FunctionDefinition(name, params, (Block) block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node visitFunctionCallExpression(KlangParser.FunctionCallExpressionContext ctx) {
|
||||
String name = ctx.functionCall().IDENT().getText();
|
||||
Expression[] args = new Expression[ctx.functionCall().arguments().expression().size()];
|
||||
for (int i = 0; i < ctx.functionCall().arguments().expression().size(); i++) {
|
||||
args[i] = (Expression) this.visit(ctx.functionCall().arguments().expression(i));
|
||||
}
|
||||
return new FunctionCall(name, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package de.hsrm.compiler.Klang.nodes;
|
||||
|
||||
import de.hsrm.compiler.Klang.visitors.Visitor;
|
||||
|
||||
public class FunctionDefinition extends Node {
|
||||
|
||||
public String name;
|
||||
public String[] parameters;
|
||||
public Block block;
|
||||
|
||||
public FunctionDefinition(String name, String[] parameters, Block block) {
|
||||
this.name = name;
|
||||
this.parameters = parameters;
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <R> R welcome(Visitor<R> v) {
|
||||
return v.visit(this);
|
||||
}
|
||||
}
|
||||
20
src/main/java/de/hsrm/compiler/Klang/nodes/Program.java
Normal file
20
src/main/java/de/hsrm/compiler/Klang/nodes/Program.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package de.hsrm.compiler.Klang.nodes;
|
||||
|
||||
import de.hsrm.compiler.Klang.nodes.expressions.Expression;
|
||||
import de.hsrm.compiler.Klang.visitors.Visitor;
|
||||
|
||||
public class Program extends Node {
|
||||
|
||||
public FunctionDefinition[] funcs;
|
||||
public Expression expression;
|
||||
|
||||
public Program(FunctionDefinition[] funcs, Expression expression) {
|
||||
this.funcs = funcs;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R welcome(Visitor<R> v) {
|
||||
return v.visit(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package de.hsrm.compiler.Klang.nodes.expressions;
|
||||
|
||||
import de.hsrm.compiler.Klang.visitors.Visitor;
|
||||
|
||||
public class FunctionCall extends Expression {
|
||||
|
||||
public String name;
|
||||
public Expression[] arguments;
|
||||
|
||||
public FunctionCall(String name, Expression[] arguments) {
|
||||
this.name = name;
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R welcome(Visitor<R> v) {
|
||||
return v.visit(this);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package de.hsrm.compiler.Klang.visitors;
|
||||
|
||||
import de.hsrm.compiler.Klang.Value;
|
||||
import de.hsrm.compiler.Klang.nodes.Block;
|
||||
import de.hsrm.compiler.Klang.nodes.FunctionDefinition;
|
||||
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||
|
||||
@@ -74,4 +75,16 @@ public class EvalVisitor implements Visitor<Value> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(FunctionDefinition e) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(FunctionCall e) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -53,6 +53,17 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
||||
this.ex = ex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(Program e) {
|
||||
for (var funcDef : e.funcs) {
|
||||
funcDef.welcome(this);
|
||||
ex.nl();
|
||||
ex.nl();
|
||||
}
|
||||
e.expression.welcome(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(IntegerExpression e) {
|
||||
ex.write(e.value);
|
||||
@@ -128,4 +139,40 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(FunctionDefinition e) {
|
||||
ex.write("function ");
|
||||
ex.write(e.name);
|
||||
ex.write(" (");
|
||||
boolean first = true;
|
||||
for (String param : e.parameters) {
|
||||
if (!first) {
|
||||
ex.write(", ");
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
ex.write(param);
|
||||
}
|
||||
ex.write(") ");
|
||||
e.block.welcome(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(FunctionCall e) {
|
||||
ex.write(e.name);
|
||||
ex.write("(");
|
||||
boolean first = true;
|
||||
for (Expression arg : e.arguments) {
|
||||
if (!first) {
|
||||
ex.write(", ");
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
arg.welcome(this);
|
||||
}
|
||||
ex.write(");");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package de.hsrm.compiler.Klang.visitors;
|
||||
|
||||
import de.hsrm.compiler.Klang.nodes.Block;
|
||||
import de.hsrm.compiler.Klang.nodes.FunctionDefinition;
|
||||
import de.hsrm.compiler.Klang.nodes.Program;
|
||||
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||
|
||||
@@ -13,4 +15,7 @@ public interface Visitor<R> {
|
||||
R visit(IfStatement e);
|
||||
R visit(PrintStatement e);
|
||||
R visit(Block e);
|
||||
R visit(FunctionDefinition e);
|
||||
R visit(FunctionCall e);
|
||||
R visit(Program e);
|
||||
}
|
||||
Reference in New Issue
Block a user