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">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.12" />
|
||||
@ -6,7 +7,7 @@
|
||||
<option name="enabled" value="true" />
|
||||
<option name="wasEnabledAtLeastOnce" value="true" />
|
||||
</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" />
|
||||
</component>
|
||||
</project>
|
@ -1,6 +1,7 @@
|
||||
JAVA = java --enable-preview
|
||||
PHASE =
|
||||
|
||||
.PHONY : %
|
||||
% : %.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 )}.
|
||||
*/
|
||||
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
|
||||
|
@ -409,8 +409,8 @@ public class LexAn implements AutoCloseable {
|
||||
nextChar();
|
||||
if (buffChar == 'n' || buffChar == '\\' || buffChar == '"') {
|
||||
} else if (isHex()) {
|
||||
nextChar();
|
||||
lexeme.append((char) buffChar);
|
||||
nextChar();
|
||||
if (!isHex()) {
|
||||
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