improved args handling in generic code

This commit is contained in:
hneemann 2019-07-11 19:24:03 +02:00
parent ccd3f1864c
commit e3c780e49d
6 changed files with 54 additions and 34 deletions

View File

@ -86,25 +86,28 @@
<elementAttributes>
<entry>
<string>generic</string>
<string>dataBits:=16;
shiftBits:=int(4);
circuit:=&quot;shift-fixed-left-inc.dig&quot;;
if (isPresent(args)) {
<string>if (isPresent(args)) {
if (args.dir=&quot;right&quot;) {
circuit=&quot;shift-fixed-right-inc.dig&quot;;
export circuit:=&quot;shift-fixed-right-inc.dig&quot;;
} else {
if (args.dir=&quot;arith&quot;) {
circuit=&quot;shift-fixed-arith-right-inc.dig&quot;;
export circuit:=&quot;shift-fixed-arith-right-inc.dig&quot;;
} else {
if (args.dir!=&quot;left&quot;) {
if (args.dir=&quot;left&quot;) {
export circuit:=&quot;shift-fixed-left-inc.dig&quot;;
} else {
panic(&quot;only \&quot;left\&quot;, \&quot;right\&quot; or \&quot;arith\&quot; is allowed as direction, not \&quot;&quot;+args.dir+&quot;\&quot;!&quot;);
}
}
}
dataBits=args.dataBits;
shiftBits=bitsNeededFor(args.dataBits-1);
export shiftBits:=bitsNeededFor(args.dataBits-1);
} else {
// used if circuit is started as the main circuit
export circuit:=&quot;shift-fixed-left-inc.dig&quot;;
export dataBits:=16;
export shiftBits:=int(4);
}</string>
</entry>
</elementAttributes>

View File

@ -13,12 +13,13 @@
<elementAttributes>
<entry>
<string>generic</string>
<string>dataBits:=16;
shift:=8;
if (isPresent(args)) {
dataBits = args.dataBits;
shift = 1&lt;&lt;(args.shiftBits-1);
<string>if (isPresent(args)) {
export shift := 1&lt;&lt;(args.shiftBits-1);
setCircuit(args.circuit);
} else {
// used if circuit is started as the main circuit
export dataBits:=16;
export shift:=8;
}</string>
</entry>
</elementAttributes>
@ -97,18 +98,18 @@ if (isPresent(args)) {
<elementAttributes>
<entry>
<string>generic</string>
<string>dataBits:=16;
shiftBits:=3;
circuit:=&quot;shift-fixed-left-inc.dig&quot;;
if (isPresent(args)) {
dataBits = args.dataBits;
<string>if (isPresent(args)) {
if (args.shiftBits=2) {
export shift := 1;
setCircuit(args.circuit);
} else {
shiftBits = args.shiftBits-1;
circuit=args.circuit;
export shiftBits := args.shiftBits-1;
}
} else {
// used if circuit is started as the main circuit
export dataBits:=16;
export shiftBits:=3;
export circuit:=&quot;shift-fixed-left-inc.dig&quot;;
}</string>
</entry>
</elementAttributes>

View File

@ -138,9 +138,7 @@ ist als drei.}}</string>
<entry>
<string>generic</string>
<string>inBits:=2;
bits:=3;
if (isPresent(args)) {
bits=args.bits;
if (args.bits&gt;3) {
setCircuit(&quot;GrayNode-inc.dig&quot;);
}

View File

@ -107,14 +107,13 @@
<elementAttributes>
<entry>
<string>generic</string>
<string>inBits:=3;
bits:=4;
if (isPresent(args)) {
inBits = args.inBits+1;
bits=args.bits;
<string>if (isPresent(args)) {
export inBits := args.inBits+1;
if (args.inBits&lt;args.bits-2) {
setCircuit(&quot;GrayNode-inc.dig&quot;);
}
} else {
export inBits:=3;
}</string>
</entry>
</elementAttributes>

View File

@ -69,7 +69,7 @@ public class ResolveGenerics {
Statement genS = getStatement(gen);
if (isCustom) {
Context mod = new Context()
.declareVar("args", args)
.declareVar("args", new ArgsGetter(args))
.declareFunc("setCircuit", new Function(1) {
@Override
protected Object f(Object... args) {
@ -81,7 +81,7 @@ public class ResolveGenerics {
ve.setGenericArgs(mod);
} else {
Context mod = new Context()
.declareVar("args", args)
.declareVar("args", new ArgsGetter(args))
.declareVar("this", new SubstituteLibrary.AllowSetAttributes(ve.getElementAttributes()));
genS.execute(mod);
}
@ -104,4 +104,23 @@ public class ResolveGenerics {
return genS;
}
private static final class ArgsGetter implements HGSMap {
private final Context args;
private ArgsGetter(Context args) {
this.args = args;
}
@Override
public Object hgsMapGet(String key) throws HGSEvalException {
Object v = args.hgsMapGet(key);
if (v == null) {
Object a = args.hgsMapGet("args");
if (a instanceof HGSMap) {
return ((HGSMap) a).hgsMapGet(key);
}
}
return v;
}
}
}

View File

@ -175,7 +175,7 @@ public class Parser {
return lino(c -> ref.declareVar(c, initVal.value(c)));
case EQUAL:
if (export)
throw newParserException("export not allowed here!");
throw newParserException("export is only allowed at variable declaration!");
final Expression val = parseExpression();
if (isRealStatement) expect(SEMICOLON);
return lino(c -> {
@ -187,18 +187,18 @@ public class Parser {
case ADD:
expect(ADD);
if (export)
throw newParserException("export not allowed here!");
throw newParserException("export is only allowed at variable declaration!");
if (isRealStatement) expect(SEMICOLON);
return lino(c -> ref.set(c, Value.toLong(ref.get(c)) + 1));
case SUB:
expect(SUB);
if (export)
throw newParserException("export not allowed here!");
throw newParserException("export is only allowed at variable declaration!");
if (isRealStatement) expect(SEMICOLON);
return lino(c -> ref.set(c, Value.toLong(ref.get(c)) - 1));
case SEMICOLON:
if (export)
throw newParserException("export not allowed here!");
throw newParserException("export is only allowed at variable declaration!");
return lino(ref::get);
default:
throw newUnexpectedToken(refToken);