Memory
This commit is contained in:
parent
e868f3030c
commit
a0cad251cd
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@ -1,3 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="Black">
|
<component name="Black">
|
||||||
<option name="sdkName" value="Python 3.12" />
|
<option name="sdkName" value="Python 3.12" />
|
||||||
@ -6,7 +7,7 @@
|
|||||||
<option name="enabled" value="true" />
|
<option name="enabled" value="true" />
|
||||||
<option name="wasEnabledAtLeastOnce" value="true" />
|
<option name="wasEnabledAtLeastOnce" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" default="true" project-jdk-name="homebrew-23" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_24" default="true" project-jdk-name="homebrew-23" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -1,6 +1,7 @@
|
|||||||
JAVA = java --enable-preview
|
JAVA = java --enable-preview
|
||||||
|
PHASE =
|
||||||
|
|
||||||
.PHONY : %
|
.PHONY : %
|
||||||
% : %.pins25
|
% : %.pins25
|
||||||
$(JAVA) -classpath ../bin pins25.phase.SynAn $<
|
$(JAVA) -classpath ../bin pins25.phase.$(PHASE) $<
|
||||||
|
|
||||||
|
153
src/pins25/common/Mem.java
Normal file
153
src/pins25/common/Mem.java
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
package pins25.common;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Klicni zapisi in dostopi do spremenljivk.
|
||||||
|
*
|
||||||
|
* Vse spremenljivke (in parametri, ki so samo posebna vrsta spremenljivke)
|
||||||
|
* katerih ime se zacne z {@code debug}, so lahko nastavljene na {@code null}.
|
||||||
|
* Uporabljajo se samo za izpis sledenja delovanja abstraktnega skladovne
|
||||||
|
* stroja.
|
||||||
|
*/
|
||||||
|
public class Mem {
|
||||||
|
|
||||||
|
@SuppressWarnings({ "doclint:missing" })
|
||||||
|
private Mem() {
|
||||||
|
throw new Report.InternalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- KLICNI ZAPISI ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Klicni zapis.
|
||||||
|
*/
|
||||||
|
public static class Frame {
|
||||||
|
|
||||||
|
/** Ime oznake, torej polno ime funkcije. */
|
||||||
|
public final String name;
|
||||||
|
|
||||||
|
/** Staticna globina funkcije. */
|
||||||
|
public final Integer depth;
|
||||||
|
|
||||||
|
/** Skupna velikost parametrov (skupaj s staticno povezavo). */
|
||||||
|
public final Integer parsSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skupna velikost lokalnih spremenljivk (skupaj s shranjenim klicnim kazalcem
|
||||||
|
* in povratnim naslovom.
|
||||||
|
*/
|
||||||
|
public final Integer varsSize;
|
||||||
|
|
||||||
|
/** Dostopi do parametrov. */
|
||||||
|
public final List<RelAccess> debugPars;
|
||||||
|
|
||||||
|
/** Dostopi do lokalnih spremenljivk. */
|
||||||
|
public final List<RelAccess> debugVars;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ustvari nov klicni zapis.
|
||||||
|
*
|
||||||
|
* @param name Ime oznake, torej polno ime funkcije.
|
||||||
|
* @param depth Staticna globina funkcije.
|
||||||
|
* @param parsSize Skupna velikost parametrov (skupaj s staticno povezavo).
|
||||||
|
* @param varsSize Skupna velikost lokalnih spremenljivk (skupaj s shranjenim
|
||||||
|
* klicnim kazalcem in povratnim naslovom.
|
||||||
|
* @param debugPars Dostopi do parametrov.
|
||||||
|
* @param debugVars Dostopi do lokalnih spremenljivk.
|
||||||
|
*/
|
||||||
|
public Frame(final String name, final Integer depth, final Integer parsSize, final Integer varsSize,
|
||||||
|
List<RelAccess> debugPars, final List<RelAccess> debugVars) {
|
||||||
|
this.name = name;
|
||||||
|
this.depth = depth;
|
||||||
|
this.parsSize = parsSize;
|
||||||
|
this.varsSize = varsSize;
|
||||||
|
this.debugPars = Collections.unmodifiableList(debugPars);
|
||||||
|
this.debugVars = Collections.unmodifiableList(debugVars);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- DOSTOPI DO SPREMENLJIVK ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dostop do spremenljivke.
|
||||||
|
*/
|
||||||
|
public static abstract class Access {
|
||||||
|
|
||||||
|
/** Velikost spremenljivke. */
|
||||||
|
public final Integer size;
|
||||||
|
|
||||||
|
/** Zacetna vrednost spremenljivke. */
|
||||||
|
public final List<Integer> inits;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ustvari nov dostop do spremenljivke.
|
||||||
|
*
|
||||||
|
* @param size Velikost spremenljivke.
|
||||||
|
* @param inits Zacetna vrednost spremenljivke.
|
||||||
|
*/
|
||||||
|
public Access(final Integer size, final Vector<Integer> inits) {
|
||||||
|
this.size = size;
|
||||||
|
this.inits = inits == null ? null : Collections.unmodifiableList(new Vector<Integer>(inits));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Absolutni dostop do spremenljivke (na staticen naslov).
|
||||||
|
*/
|
||||||
|
public static class AbsAccess extends Access {
|
||||||
|
|
||||||
|
/** Ime oznake (ime spremenljivke). */
|
||||||
|
public final String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ustvari nov absolutni dostop do spremenljivke.
|
||||||
|
*
|
||||||
|
* @param name Ime oznake (ime spremenljivke).
|
||||||
|
* @param size Velikost spremenljivke.
|
||||||
|
* @param inits Zacetna vrednost spremenljivke.
|
||||||
|
*/
|
||||||
|
public AbsAccess(final String name, final Integer size, final Vector<Integer> inits) {
|
||||||
|
super(size, inits);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relativni dostop do spremenljivke (na skladu).
|
||||||
|
*/
|
||||||
|
public static class RelAccess extends Access {
|
||||||
|
|
||||||
|
/** Odmik od vrha klicnega zapisa, torej od vrednosti klicnega kazalca. */
|
||||||
|
public final Integer offset;
|
||||||
|
|
||||||
|
/** Staticna globina spremenljivke. */
|
||||||
|
public final Integer depth;
|
||||||
|
|
||||||
|
/** Ime spremenljivke. */
|
||||||
|
public final String debugName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ustvari nov relativni dostop do spremenljivke.
|
||||||
|
*
|
||||||
|
* @param offset Odmik od vrha klicnega zapisa, torej od vrednosti klicnega
|
||||||
|
* kazalca.
|
||||||
|
* @param depth Staticna globina spremenljivke.
|
||||||
|
* @param size Velikost spremenljivke.
|
||||||
|
* @param inits Zacetna vrednost spremenljivke.
|
||||||
|
* @param debugName Ime spremenljivke.
|
||||||
|
*/
|
||||||
|
public RelAccess(final Integer offset, final Integer depth, Integer size, final Vector<Integer> inits,
|
||||||
|
final String debugName) {
|
||||||
|
super(size, inits);
|
||||||
|
this.offset = offset;
|
||||||
|
this.depth = depth;
|
||||||
|
this.debugName = debugName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -149,46 +149,6 @@ public record Token(Report.Location location, Symbol symbol, String lexeme) impl
|
|||||||
* Simbol {@code )}.
|
* Simbol {@code )}.
|
||||||
*/
|
*/
|
||||||
RPAREN;
|
RPAREN;
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return switch (this) {
|
|
||||||
case INTCONST -> "integer constant";
|
|
||||||
case CHARCONST -> "character constant";
|
|
||||||
case STRINGCONST -> "string constant";
|
|
||||||
case IDENTIFIER -> "identifier";
|
|
||||||
case FUN -> "'fun'";
|
|
||||||
case VAR -> "'var'";
|
|
||||||
case IF -> "'if'";
|
|
||||||
case THEN -> "'then'";
|
|
||||||
case ELSE -> "'else'";
|
|
||||||
case WHILE -> "'while'";
|
|
||||||
case DO -> "'do'";
|
|
||||||
case LET -> "'let'";
|
|
||||||
case IN -> "'in'";
|
|
||||||
case END -> "'end'";
|
|
||||||
case ASSIGN -> "'='";
|
|
||||||
case COMMA -> "','";
|
|
||||||
case AND -> "'&&'";
|
|
||||||
case OR -> "'||'";
|
|
||||||
case NOT -> "'!'";
|
|
||||||
case EQU -> "'=='";
|
|
||||||
case NEQ -> "'!='";
|
|
||||||
case GTH -> "'>'";
|
|
||||||
case LTH -> "'<'";
|
|
||||||
case GEQ -> "'>='";
|
|
||||||
case LEQ -> "'<='";
|
|
||||||
case ADD -> "'+'";
|
|
||||||
case SUB -> "'-'";
|
|
||||||
case MUL -> "'*'";
|
|
||||||
case DIV -> "'/'";
|
|
||||||
case MOD -> "'%'";
|
|
||||||
case PTR -> "'^'";
|
|
||||||
case LPAREN -> "'('";
|
|
||||||
case RPAREN -> "')'";
|
|
||||||
default -> this.toString();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -409,8 +409,8 @@ public class LexAn implements AutoCloseable {
|
|||||||
nextChar();
|
nextChar();
|
||||||
if (buffChar == 'n' || buffChar == '\\' || buffChar == '"') {
|
if (buffChar == 'n' || buffChar == '\\' || buffChar == '"') {
|
||||||
} else if (isHex()) {
|
} else if (isHex()) {
|
||||||
nextChar();
|
|
||||||
lexeme.append((char) buffChar);
|
lexeme.append((char) buffChar);
|
||||||
|
nextChar();
|
||||||
if (!isHex()) {
|
if (!isHex()) {
|
||||||
throw new Report.Error(currentLocation(), "Invalid ascii code '" + (char) buffChar + "'.");
|
throw new Report.Error(currentLocation(), "Invalid ascii code '" + (char) buffChar + "'.");
|
||||||
}
|
}
|
||||||
|
422
src/pins25/phase/Memory.java
Normal file
422
src/pins25/phase/Memory.java
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
package pins25.phase;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import pins25.common.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Izracun pomnilniske predstavitve.
|
||||||
|
*/
|
||||||
|
public class Memory {
|
||||||
|
|
||||||
|
@SuppressWarnings({"doclint:missing"})
|
||||||
|
public Memory() {
|
||||||
|
throw new Report.InternalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraktno sintaksno drevo z dodanimi atributi izracuna pomnilniske
|
||||||
|
* predstavitve.
|
||||||
|
* <p>
|
||||||
|
* Atributi:
|
||||||
|
* <ol>
|
||||||
|
* <li>({@link Abstr}) lokacija kode, ki pripada posameznemu vozliscu;</li>
|
||||||
|
* <li>({@link SemAn}) definicija uporabljenega imena;</li>
|
||||||
|
* <li>({@link SemAn}) ali je dani izraz levi izraz;</li>
|
||||||
|
* <li>({@link Memory}) klicni zapis funkcije;</li>
|
||||||
|
* <li>({@link Memory}) dostop do parametra;</li>
|
||||||
|
* <li>({@link Memory}) dostop do spremenljivke.</li>
|
||||||
|
* </ol>
|
||||||
|
*/
|
||||||
|
public static class AttrAST extends SemAn.AttrAST {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atribut: klicni zapis funkcije.
|
||||||
|
*/
|
||||||
|
public final Map<AST.FunDef, Mem.Frame> attrFrame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atribut: dostop do parametra.
|
||||||
|
*/
|
||||||
|
public final Map<AST.ParDef, Mem.RelAccess> attrParAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atribut: dostop do spremenljivke.
|
||||||
|
*/
|
||||||
|
public final Map<AST.VarDef, Mem.Access> attrVarAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ustvari novo abstraktno sintaksno drevo z dodanimi atributi izracuna
|
||||||
|
* pomnilniske predstavitve.
|
||||||
|
*
|
||||||
|
* @param attrAST Abstraktno sintaksno drevo z dodanimi atributi
|
||||||
|
* semanticne analize.
|
||||||
|
* @param attrFrame Attribut: klicni zapis funkcije.
|
||||||
|
* @param attrParAccess Attribut: dostop do parametra.
|
||||||
|
* @param attrVarAccess Attribut: dostop do spremenljivke.
|
||||||
|
*/
|
||||||
|
public AttrAST(final SemAn.AttrAST attrAST, final Map<AST.FunDef, Mem.Frame> attrFrame,
|
||||||
|
final Map<AST.ParDef, Mem.RelAccess> attrParAccess, final Map<AST.VarDef, Mem.Access> attrVarAccess) {
|
||||||
|
super(attrAST);
|
||||||
|
this.attrFrame = attrFrame;
|
||||||
|
this.attrParAccess = attrParAccess;
|
||||||
|
this.attrVarAccess = attrVarAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ustvari novo abstraktno sintaksno drevo z dodanimi atributi izracuna
|
||||||
|
* pomnilniske predstavitve.
|
||||||
|
*
|
||||||
|
* @param attrAST Abstraktno sintaksno drevo z dodanimi atributi izracuna
|
||||||
|
* pomnilniske predstavitve.
|
||||||
|
*/
|
||||||
|
public AttrAST(final AttrAST attrAST) {
|
||||||
|
super(attrAST);
|
||||||
|
this.attrFrame = attrAST.attrFrame;
|
||||||
|
this.attrParAccess = attrAST.attrParAccess;
|
||||||
|
this.attrVarAccess = attrAST.attrVarAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String head(final AST.Node node, final boolean highlighted) {
|
||||||
|
final StringBuffer head = new StringBuffer();
|
||||||
|
head.append(super.head(node, false));
|
||||||
|
head.append(highlighted ? "\033[31m" : "");
|
||||||
|
switch (node) {
|
||||||
|
case final AST.FunDef funDef:
|
||||||
|
Mem.Frame frame = attrFrame.get(funDef);
|
||||||
|
head.append(" depth=" + frame.depth);
|
||||||
|
head.append(" parsSize=" + frame.parsSize);
|
||||||
|
head.append(" varsSize=" + frame.varsSize);
|
||||||
|
break;
|
||||||
|
case final AST.ParDef parDef: {
|
||||||
|
Mem.RelAccess relAccess = attrParAccess.get(parDef);
|
||||||
|
head.append(" offset=" + relAccess.offset);
|
||||||
|
head.append(" size=" + relAccess.size);
|
||||||
|
head.append(" depth=" + relAccess.depth);
|
||||||
|
if (relAccess.inits != null)
|
||||||
|
initsToString(relAccess.inits, head);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case final AST.VarDef varDef: {
|
||||||
|
Mem.Access access = attrVarAccess.get(varDef);
|
||||||
|
if (access != null)
|
||||||
|
switch (access) {
|
||||||
|
case final Mem.AbsAccess absAccess:
|
||||||
|
head.append(" size=" + absAccess.size);
|
||||||
|
if (absAccess.inits != null)
|
||||||
|
initsToString(absAccess.inits, head);
|
||||||
|
break;
|
||||||
|
case final Mem.RelAccess relAccess:
|
||||||
|
head.append(" offset=" + relAccess.offset);
|
||||||
|
head.append(" size=" + relAccess.size);
|
||||||
|
head.append(" depth=" + relAccess.depth);
|
||||||
|
if (relAccess.inits != null)
|
||||||
|
initsToString(relAccess.inits, head);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Report.InternalError();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
head.append(highlighted ? "\033[30m" : "");
|
||||||
|
return head.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pripravi znakovno predstavitev zacetne vrednosti spremenmljivke.
|
||||||
|
*
|
||||||
|
* @param inits Zacetna vrednost spremenljivke.
|
||||||
|
* @param head Znakovno predstavitev zacetne vrednosti spremenmljivke.
|
||||||
|
*/
|
||||||
|
private void initsToString(final List<Integer> inits, final StringBuffer head) {
|
||||||
|
head.append(" inits=");
|
||||||
|
int numPrintedVals = 0;
|
||||||
|
int valPtr = 1;
|
||||||
|
for (int init = 0; init < inits.get(0); init++) {
|
||||||
|
final int num = inits.get(valPtr++);
|
||||||
|
final int len = inits.get(valPtr++);
|
||||||
|
int oldp = valPtr;
|
||||||
|
for (int n = 0; n < num; n++) {
|
||||||
|
valPtr = oldp;
|
||||||
|
for (int l = 0; l < len; l++) {
|
||||||
|
if (numPrintedVals == 10) {
|
||||||
|
head.append("...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
head.append((numPrintedVals > 0 ? "," : "") + inits.get(valPtr++));
|
||||||
|
numPrintedVals++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opravi izracun pomnilniske predstavitve.
|
||||||
|
*
|
||||||
|
* @param semanAttrAST Abstraktno sintaksno drevo z dodanimi atributi izracuna
|
||||||
|
* pomnilniske predstavitve.
|
||||||
|
* @return Abstraktno sintaksno drevo z atributi po fazi pomnilniske
|
||||||
|
* predstavitve.
|
||||||
|
*/
|
||||||
|
public static AttrAST organize(SemAn.AttrAST semanAttrAST) {
|
||||||
|
AttrAST attrAST = new AttrAST(semanAttrAST, new HashMap<AST.FunDef, Mem.Frame>(),
|
||||||
|
new HashMap<AST.ParDef, Mem.RelAccess>(), new HashMap<AST.VarDef, Mem.Access>());
|
||||||
|
(new MemoryOrganizer(attrAST)).organize();
|
||||||
|
return attrAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Organizator pomnilniske predstavitve.
|
||||||
|
*/
|
||||||
|
private static class MemoryOrganizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraktno sintaksno drevo z dodanimi atributi izracuna pomnilniske
|
||||||
|
* predstavitve.
|
||||||
|
*/
|
||||||
|
private final AttrAST attrAST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ustvari nov organizator pomnilniske predstavitve.
|
||||||
|
*
|
||||||
|
* @param attrAST Abstraktno sintaksno drevo z dodanimi atributi izracuna
|
||||||
|
* pomnilniske predstavitve.
|
||||||
|
*/
|
||||||
|
public MemoryOrganizer(final AttrAST attrAST) {
|
||||||
|
this.attrAST = attrAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sprozi nov izracun pomnilniske predstavitve.
|
||||||
|
*
|
||||||
|
* @return Abstraktno sintaksno drevo z dodanimi atributi izracuna pomnilniske
|
||||||
|
* predstavitve.
|
||||||
|
*/
|
||||||
|
public AttrAST organize() {
|
||||||
|
attrAST.ast.accept(new MemoryVisitor(), null);
|
||||||
|
return new AttrAST(attrAST, Collections.unmodifiableMap(attrAST.attrFrame),
|
||||||
|
Collections.unmodifiableMap(attrAST.attrParAccess),
|
||||||
|
Collections.unmodifiableMap(attrAST.attrVarAccess));
|
||||||
|
}
|
||||||
|
|
||||||
|
static private class FrameBuilder {
|
||||||
|
int depth = 0;
|
||||||
|
int varOffset = 8; // FP + RA
|
||||||
|
Vector<Mem.RelAccess> debugVars = new Vector<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obiskovalec, ki izracuna pomnilnisko predstavitev.
|
||||||
|
*/
|
||||||
|
private class MemoryVisitor implements AST.FullVisitor<FrameBuilder, FrameBuilder> {
|
||||||
|
|
||||||
|
@SuppressWarnings({"doclint:missing"})
|
||||||
|
public MemoryVisitor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FrameBuilder visit(AST.FunDef funDef, FrameBuilder upperFB) {
|
||||||
|
FrameBuilder frameBuilder = new FrameBuilder();
|
||||||
|
if (upperFB != null) {
|
||||||
|
frameBuilder.depth = upperFB.depth + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parOffset = 4; // +SL
|
||||||
|
Vector<Mem.RelAccess> debugPars = new Vector<>();
|
||||||
|
for (AST.ParDef parDef : funDef.pars) {
|
||||||
|
Vector<Integer> inits = new Vector<>();
|
||||||
|
inits.add(1);
|
||||||
|
inits.add(1);
|
||||||
|
inits.add(1);
|
||||||
|
inits.add(0);
|
||||||
|
Mem.RelAccess access = new Mem.RelAccess(parOffset, frameBuilder.depth, 4, inits, parDef.name);
|
||||||
|
parOffset += access.size;
|
||||||
|
debugPars.add(access);
|
||||||
|
attrAST.attrParAccess.put(parDef, access);
|
||||||
|
}
|
||||||
|
|
||||||
|
AST.FullVisitor.super.visit(funDef, frameBuilder);
|
||||||
|
|
||||||
|
Mem.Frame frame = new Mem.Frame(
|
||||||
|
funDef.name,
|
||||||
|
frameBuilder.depth,
|
||||||
|
parOffset,
|
||||||
|
frameBuilder.varOffset,
|
||||||
|
debugPars,
|
||||||
|
frameBuilder.debugVars
|
||||||
|
);
|
||||||
|
attrAST.attrFrame.put(funDef, frame);
|
||||||
|
|
||||||
|
return upperFB;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FrameBuilder visit(AST.VarDef varDef, FrameBuilder frameBuilder) {
|
||||||
|
Vector<Integer> inits = new Vector<>();
|
||||||
|
inits.add(varDef.inits.size());
|
||||||
|
for (AST.Init init : varDef.inits) {
|
||||||
|
Report.Locatable valLoc = attrAST.attrLoc.get(init.value);
|
||||||
|
Report.Locatable numLoc = attrAST.attrLoc.get(init.num);
|
||||||
|
|
||||||
|
inits.add(decodeIntConst(init.num, numLoc));
|
||||||
|
|
||||||
|
switch (init.value.type) {
|
||||||
|
case INTCONST:
|
||||||
|
inits.add(1);
|
||||||
|
inits.add(decodeIntConst(init.value, valLoc));
|
||||||
|
break;
|
||||||
|
case CHRCONST:
|
||||||
|
inits.add(1);
|
||||||
|
inits.add(decodeChrConst(init.value, valLoc));
|
||||||
|
break;
|
||||||
|
case STRCONST:
|
||||||
|
Vector<Integer> str = decodeStrConst(init.value, valLoc);
|
||||||
|
inits.add(str.size());
|
||||||
|
inits.addAll(str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frameBuilder == null) {
|
||||||
|
Mem.AbsAccess access = new Mem.AbsAccess(varDef.name, inits.size(), inits);
|
||||||
|
attrAST.attrVarAccess.put(varDef, access);
|
||||||
|
} else {
|
||||||
|
Mem.RelAccess access = new Mem.RelAccess(frameBuilder.varOffset, frameBuilder.depth, inits.size(), inits, varDef.name);
|
||||||
|
frameBuilder.varOffset += inits.size();
|
||||||
|
frameBuilder.debugVars.add(access);
|
||||||
|
attrAST.attrVarAccess.put(varDef, access);
|
||||||
|
}
|
||||||
|
|
||||||
|
return frameBuilder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Izracuna vrednost celostevilske konstante.
|
||||||
|
*
|
||||||
|
* @param intAtomExpr Celostevilska konstanta.
|
||||||
|
* @param loc Lokacija celostevilske konstante.
|
||||||
|
* @return Vrednost celostevilske konstante.
|
||||||
|
*/
|
||||||
|
public static Integer decodeIntConst(final AST.AtomExpr intAtomExpr, final Report.Locatable loc) {
|
||||||
|
try {
|
||||||
|
return Integer.decode(intAtomExpr.value);
|
||||||
|
} catch (NumberFormatException __) {
|
||||||
|
throw new Report.Error(loc, "Illegal integer value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Izracuna vrednost znakovna konstante.
|
||||||
|
*
|
||||||
|
* @param chrAtomExpr Znakovna konstanta.
|
||||||
|
* @param loc Lokacija znakovne konstante.
|
||||||
|
* @return Vrednost znakovne konstante.
|
||||||
|
*/
|
||||||
|
public static Integer decodeChrConst(final AST.AtomExpr chrAtomExpr, final Report.Locatable loc) {
|
||||||
|
switch (chrAtomExpr.value.charAt(1)) {
|
||||||
|
case '\\':
|
||||||
|
switch (chrAtomExpr.value.charAt(2)) {
|
||||||
|
case 'n':
|
||||||
|
return 10;
|
||||||
|
case '\'':
|
||||||
|
return ((int) '\'');
|
||||||
|
case '\\':
|
||||||
|
return ((int) '\\');
|
||||||
|
default:
|
||||||
|
return 16 * (((int) chrAtomExpr.value.charAt(2)) - ((int) '0'))
|
||||||
|
+ (((int) chrAtomExpr.value.charAt(3)) - ((int) '0'));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return ((int) chrAtomExpr.value.charAt(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Izracuna vrednost konstantnega niza.
|
||||||
|
*
|
||||||
|
* @param strAtomExpr Konstantni niz.
|
||||||
|
* @param loc Lokacija konstantnega niza.
|
||||||
|
* @return Vrendnost konstantega niza.
|
||||||
|
*/
|
||||||
|
public static Vector<Integer> decodeStrConst(final AST.AtomExpr strAtomExpr, final Report.Locatable loc) {
|
||||||
|
final Vector<Integer> value = new Vector<Integer>();
|
||||||
|
for (int c = 1; c < strAtomExpr.value.length() - 1; c++) {
|
||||||
|
switch (strAtomExpr.value.charAt(c)) {
|
||||||
|
case '\\':
|
||||||
|
switch (strAtomExpr.value.charAt(c + 1)) {
|
||||||
|
case 'n':
|
||||||
|
value.addLast(10);
|
||||||
|
c += 1;
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
value.addLast((int) '\"');
|
||||||
|
c += 1;
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
value.addLast((int) '\\');
|
||||||
|
c += 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
value.addLast(16 * (((int) strAtomExpr.value.charAt(c + 1)) - ((int) '0'))
|
||||||
|
+ (((int) strAtomExpr.value.charAt(c + 2)) - ((int) '0')));
|
||||||
|
c += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
value.addLast((int) strAtomExpr.value.charAt(c));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- ZAGON ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zagon izracuna pomnilniske predstavitve kot samostojnega programa.
|
||||||
|
*
|
||||||
|
* @param cmdLineArgs Argumenti v ukazni vrstici.
|
||||||
|
*/
|
||||||
|
public static void main(final String[] cmdLineArgs) {
|
||||||
|
System.out.println("This is PINS'25 compiler (memory):");
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (cmdLineArgs.length == 0)
|
||||||
|
throw new Report.Error("No source file specified in the command line.");
|
||||||
|
if (cmdLineArgs.length > 1)
|
||||||
|
Report.warning("Unused arguments in the command line.");
|
||||||
|
|
||||||
|
try (SynAn synAn = new SynAn(cmdLineArgs[0])) {
|
||||||
|
// abstraktna sintaksa:
|
||||||
|
final Abstr.AttrAST abstrAttrAST = Abstr.constructAST(synAn);
|
||||||
|
// semanticna analiza:
|
||||||
|
final SemAn.AttrAST semanAttrAST = SemAn.analyze(abstrAttrAST);
|
||||||
|
// pomnilniska predstavitev:
|
||||||
|
final AttrAST memoryAttrAST = Memory.organize(semanAttrAST);
|
||||||
|
|
||||||
|
(new AST.Logger(memoryAttrAST)).log();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upajmo, da kdaj pridemo to te tocke.
|
||||||
|
// A zavedajmo se sledecega:
|
||||||
|
// 1. Prevod je zaradi napak v programu lahko napacen :-o
|
||||||
|
// 2. Izvorni program se zdalec ni tisto, kar je programer hotel, da bi bil ;-)
|
||||||
|
Report.info("Done.");
|
||||||
|
} catch (Report.Error error) {
|
||||||
|
// Izpis opisa napake.
|
||||||
|
System.err.println(error.getMessage());
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user