// [PM] 4.3.2 public virtual void writeVariable(PBVariable var) { if (variableTable == null) { variableTable = new System.Collections.Hashtable(); } byte[] variableNameBytes = (byte[])variableTable [var]; if (variableNameBytes == null) { variableNameBytes = UTF8encoder.GetBytes(Convert.ToString(variableTable.Count)); variableTable [var] = variableNameBytes; } writeTaggedBytes(FastParser.VARIABLE, variableNameBytes); }
/* * [PM] 4.1.3 Manage an explicit stack to avoid running out of Java stack * (SPRM 11909) */ PBTerm parseTerm(System.IO.Stream stream) { Work outer = new Work(new PBTerm[1], null); Work stack = outer; do { int chr = stream.ReadByte(); PBTerm term; if (FastParser.logging) { Console.Out.WriteLine("parseTerm() switch on " + chr); } switch (chr) { case INTEGER: { string val = getString(stream); // return new PBInteger(val); try { term = new PBInteger(Convert.ToInt64(val, 10), val); } catch (FormatException /* nfe */) { // FIXME: Perhaps not catch FormatException? If malformed then it is no bignum either. term = new PBBignum(BigInteger.Parse(val), val); } catch (OverflowException) { term = new PBBignum(BigInteger.Parse(val), val); } if (logging) { Console.Out.WriteLine("bump() INTEGER " + val); } stack = stack.bump(term); } break; case FLOAT: { string val = getString(stream); term = new PBFloat(Double.Parse(val), val); if (logging) { Console.Out.WriteLine("bump() FLOAT " + val); } stack = stack.bump(term); } break; case ATOM: { string val = getString(stream); term = PBTerm.makeAtom(val); if (logging) { Console.Out.WriteLine("bump() ATOM " + val); } stack = stack.bump(term); } break; case VARIABLE: { string val = '_' + getString(stream); if (variableTable == null) { variableTable = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); } PBVariable var = (PBVariable)variableTable [val]; if (var == null) { var = new PBVariable(val); variableTable [val] = var; } term = var; if (logging) { Console.Out.WriteLine("bump() VARIABLE " + val); } stack = stack.bump(term); } break; case STRING: { byte[] val = getBytes(stream); PBTerm t = parseTerm(stream); // Note that this builds the list from the end. for (int i = val.Length - 1; i >= 0; i--) { t = PBTerm.makeTerm(new PBInteger(val [i]), t); } term = t; if (logging) { Console.Out.WriteLine("bump() STRING " + val); } stack = stack.bump(term); } break; case LIST: { const int noTerms = 2; PBTerm[] terms = new PBTerm[noTerms]; term = new PBListCell(terms); if (logging) { Console.Out.WriteLine("bump() LIST ./2"); } stack = stack.bump(term, terms); } break; case NIL: { term = PBTerm.NIL; if (logging) { Console.Out.WriteLine("bump() NIL"); } stack = stack.bump(term); } break; case COMPOUND: { string val = getString(stream); int noTerms = stream.ReadByte(); PBTerm[] terms = new PBTerm[noTerms]; term = PBTerm.makeTerm(val, terms); if (logging) { Console.Out.WriteLine("bump() COMPOUND " + val + "/" + noTerms); } stack = stack.bump(term, terms); } break; default: throw new System.IO.IOException("Parse error: illegal character " + (char)chr); } } while (stack != null); // assert outer != null; // assert outer.args != null && outer.args.length == 1; // assert validTerm(outer.args[0]); if (logging) { Console.Out.WriteLine("parseTermWithStack returning " + outer.args [0]); } return(outer.args [0]); }