Skip to content

Commit

Permalink
1. Updated instruction format and explanations in VM_Design.md.
Browse files Browse the repository at this point in the history
2. Removed unnecessary code in CymbolAssembler.
3. Updated dependencies in pom.xml.
  • Loading branch information
whtoo committed Nov 3, 2023
1 parent 8df924f commit e0d4346
Show file tree
Hide file tree
Showing 13 changed files with 290 additions and 175 deletions.
44 changes: 23 additions & 21 deletions ep18/VM_Design.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,29 @@
> 默认的f前缀指的是有符号32位浮点
| 指令 | 格式 | 说明 |
|--------|-------------------------|--------------------------------|
| imult | imult | 连续从栈顶弹出2个整数,并相乘。然后,将结果押入栈顶。 |
| idiv | idiv | 连续从栈顶弹出2个整数,并相除。然后,将结果押入栈顶。 |
| iadd | iadd | 连续从栈顶弹出2个整数,并相加。然后,将结果押入栈顶。 |
| isub | isub | 连续从栈顶弹出2个整数,并相减。然后,将结果押入栈顶。 |
| iconst | iconst int | 向栈顶压入一个整数 |
| fmult | fmult | 连续从栈顶弹出2个整数,并相乘。然后,将结果押入栈顶。 |
| fdiv | fdiv | 连续从栈顶弹出2个整数,并相除。然后,将结果押入栈顶。 |
| fadd | fadd | 连续从栈顶弹出2个整数,并相加。然后,将结果押入栈顶。 |
| fsub | fsub | 连续从栈顶弹出2个整数,并相减。然后,将结果押入栈顶。 |
| fconst | fconst float | 向栈顶压入一个字符串常量 |
| sconst | sconst string | 向栈顶压入一个字符串常量 |
| ret | ret | 函数调用返回到调用点 |
| gload | gload operands-Index | |
| gstore | gstore operands-Index | |
| load | load operands-Index | |
| store | store operands-Index | |
| br | br pc | 无条件跳转到`pc`指向的指令位置 |
| brt | br code-addr | 当操作数栈顶为`true`时,跳转到`pc`指向的指令位置 |
| brf | br code-addr | 当操作数栈顶为`false`时,跳转到`pc`指向的指令位置 |
| 指令 | 格式 | 说明 |
|--------|-------------------------|-------------------------------------|
| imult | imult | 连续从栈顶弹出2个整数,并相乘。然后,将结果押入栈顶。 |
| idiv | idiv | 连续从栈顶弹出2个整数,并相除。然后,将结果押入栈顶。 |
| iadd | iadd | 连续从栈顶弹出2个整数,并相加。然后,将结果押入栈顶。 |
| isub | isub | 连续从栈顶弹出2个整数,并相减。然后,将结果押入栈顶。 |
| iconst | iconst int | 向栈顶压入一个整数 |
| fmult | fmult | 连续从栈顶弹出2个整数,并相乘。然后,将结果押入栈顶。 |
| fdiv | fdiv | 连续从栈顶弹出2个整数,并相除。然后,将结果押入栈顶。 |
| fadd | fadd | 连续从栈顶弹出2个整数,并相加。然后,将结果押入栈顶。 |
| fsub | fsub | 连续从栈顶弹出2个整数,并相减。然后,将结果押入栈顶。 |
| fconst | fconst float | 向栈顶压入一个字符串常量 |
| sconst | sconst string | 向栈顶压入一个字符串常量 |
| ret | ret | 函数调用返回到调用点 |
| gload | gload operands-Index | |
| gstore | gstore operands-Index | |
| iload | load operands-Index | 将栈顶元素弹出然后写入Frame的`operands-Index`位置 |
| istore | store operands-Index | 将Frame的`operands-Index`位置元素压入栈 |
| br | br pc | 无条件跳转到`pc`指向的指令位置 |
| brt | br code-addr | 当操作数栈顶为`true`时,跳转到`pc`指向的指令位置 |
| brf | br code-addr | 当操作数栈顶为`false`时,跳转到`pc`指向的指令位置 |
| call | call funcname'()' | 调用`funcname` |
| halt | halt | 程序终止 |



41 changes: 36 additions & 5 deletions ep18/src/main/resources/t.vm
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
.def main: args=0 ,locals=0
.def dec1: args=1 ,locals=1:
iconst 1
iload 0
br L2
L2:
ret
.def main: args=0 ,locals=1:
iconst 10
print
istore 0
br L5
L5:
iconst 0
br main_0
main_0 :
halt
iload 0
brf L7
L6:
iconst 5
iload 0
brf L9
L8:
iload 0
call print()
iconst 7
iload 0
brf L11
L10:
iconst 7
br L4
L9:
call print()
iload 0
call dec1()
istore 0
br L5
L7:
iconst 0
br L4
L4:
ret
12 changes: 12 additions & 0 deletions ep20/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@
<version>1.5.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
<scope>compile</scope>
</dependency>
</dependencies>


Expand Down
35 changes: 28 additions & 7 deletions ep20/src/main/java/org/teachfx/antlr4/ep20/Compiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@
//import org.teachfx.antlr4.ep20.pass.ir.CymbolIRBuilder;
import org.teachfx.antlr4.ep20.pass.cfg.BasicBlock;
import org.teachfx.antlr4.ep20.pass.cfg.ControlFlowAnalysis;
import org.teachfx.antlr4.ep20.pass.codegen.CymbolAssembler;
import org.teachfx.antlr4.ep20.pass.ir.CymbolIRBuilder;
import org.teachfx.antlr4.ep20.pass.symtab.LocalDefine;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.util.List;

public class Compiler {
Expand Down Expand Up @@ -54,10 +52,33 @@ public static void main(String[] args) throws IOException {
var irBuilder = new CymbolIRBuilder();

astRoot.accept(irBuilder);
printIRTree(irBuilder.prog.linearInstrs());
// printIRTree(irBuilder.prog.linearInstrs());

var dataFlowAnalysis = new ControlFlowAnalysis();
irBuilder.prog.accept(dataFlowAnalysis);
var assembler = new CymbolAssembler();
irBuilder.prog.accept(assembler);
saveToEp18Res(assembler.getAsmInfo());
}

protected static void saveToEp18Res(String buffer) {
String modulePath = "../ep18/src/main/resources"; // 替换 "my-module" 为你的模块名称
File moduleDirectory = new File(modulePath);
logger.info("file path %s".formatted(moduleDirectory.getAbsolutePath()));
if (moduleDirectory.exists()) {
logger.info("模块路径:" + moduleDirectory.getAbsolutePath());
var filePath = modulePath+"/t.vm";
File file = new File(filePath);
try (var outputStream = new FileOutputStream(file)) {
if (!file.exists()) {
file.createNewFile();
}
outputStream.write(buffer.getBytes());

} catch (IOException e) {
throw new RuntimeException(e);
}

} else {
logger.error("模块路径不存在!");
}
}
}
22 changes: 22 additions & 0 deletions ep20/src/main/java/org/teachfx/antlr4/ep20/driver/Task.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.teachfx.antlr4.ep20.driver;
import java.util.Optional;
import java.util.function.Function;

/**
* Represents a "task" function that accepts one argument and may produce a result. Can be regarded as a "partial"
* function.
*/
public interface Task<T, R> extends Function<T, Optional<R>> {
/**
* Pipe two tasks. This will return a function which does "this" first, if succeeds, continue do {@code next} with
* the previous result as input; or else exits and returns {@link Optional#empty}.
* <p>
* In terms of monad, this is just a Kleisli composition.
*
* @param next the next function
* @return the piped (Kleisli-composed) function
*/
default <V> Task<T, V> then(Task<R, V> next) {
return t -> this.apply(t).flatMap(next);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public interface IRVisitor<S,E> {
default S visit(Stmt stmt) { return stmt.accept(this);}

S visit(ReturnVal returnVal);
S visit(ExprStmt exprStmt);
default S visit(ExprStmt exprStmt) { return exprStmt.accept(this); }

S visit(Prog prog);

Expand Down
22 changes: 21 additions & 1 deletion ep20/src/main/java/org/teachfx/antlr4/ep20/ir/Prog.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.teachfx.antlr4.ep20.ir;

import org.teachfx.antlr4.ep20.ir.stmt.FuncEntryLabel;
import org.teachfx.antlr4.ep20.ir.stmt.Label;
import org.teachfx.antlr4.ep20.pass.cfg.BasicBlock;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


public class Prog extends IRNode {
Expand Down Expand Up @@ -45,6 +47,24 @@ public List<IRNode> linearInstrs() {
linearInstrsImpl(block);
}

return instrs;
var buffer = new ArrayList<IRNode>();
IRNode prev = null;
IRNode cur = null;

for (IRNode instr : instrs) {
prev = cur;
cur = instr;
if (Objects.nonNull(prev) && prev instanceof Label) {
if (cur instanceof FuncEntryLabel) {
buffer.remove(prev);
}
}

buffer.add(cur);
}

return buffer;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ public static FrameSlot get(VariableSymbol variableSymbol) {
public FrameSlot(int idx) {
this.slotIdx = idx;
}
public int getSlotIdx() {
return slotIdx;
}

@Override
public <S, E> E accept(IRVisitor<S, E> visitor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public static StackSlot genTemp() {
private StackSlot() {
this.ord = StackSlot.ordSeq++;
}
public int getOrd() {
return ord;
}

@Override
public String toString() {
Expand Down
Loading

0 comments on commit e0d4346

Please sign in to comment.