public void SchemeASTTest() { SchemeAST root = new SchemeAST(); SchemeAST ast = new SchemeAST( root, SchemeNil.instance ); Assert.IsTrue( ast.parent == root ); SchemeAST child1 = new SchemeAST( ast, SchemeNil.instance ); SchemeAST child2 = new SchemeAST( child1, SchemeTrue.instance ); child1.children.Add( child2 ); ast.children.Add( child1 ); Assert.IsTrue( ast.children.Count == 1 ); Assert.IsTrue( ast.children[0].parent == ast ); Assert.IsTrue( ast.currentObject == SchemeNil.instance ); Assert.IsTrue( ast.children[0].children.Count == 1 ); Assert.IsTrue( ast.children[0].children[0] == child2 ); Assert.IsTrue( ast.children[0].children[0].parent == child1 ); Assert.IsTrue( ast.children[0].children[0].currentObject == SchemeTrue.instance ); SchemeAST clone = (SchemeAST)ast.Clone(); Assert.AreEqual( clone, ast ); // Assert.AreEqual( clone, ast ); }
public SchemeAST parseString( string input ) { SchemeAST root = new SchemeAST(); SchemeAST currentParent = root; var tokens = tokenize( input ); for( int i = 0; i < tokens.Count; i++ ) { string token = tokens[i]; if( token == "(" ) { var j = 1 + i; if( tokens[j] == ")" ) //peek if void { currentParent.children.Add(new SchemeAST( currentParent, SchemeVoid.instance )); i += 2; } var oldParent = currentParent; currentParent = new SchemeAST( oldParent, makeSchemeObject( tokens[++i] ) ); //make new ast node and assign it to the parent. Also advance the counter! oldParent.children.Add( currentParent ); } else if( token == ")" ) { currentParent = currentParent.parent; //jump up one level } else { currentParent.children.Add( new SchemeAST( currentParent, makeSchemeObject( token ) ) ); } } return root; }
public List<SchemeObject> evaluate(SchemeAST AST) { if (currentEnvironment == null) { currentEnvironment = root; } return evaluate(ref AST); }
public object Clone() { SchemeAST ast = new SchemeAST( _parent, currentObject ); ast.hasOwnEnviornment = this.hasOwnEnviornment; foreach( SchemeAST child in children ) { ast.children.Add( (SchemeAST) child.Clone() ); } return ast; }
internal List<SchemeObject> evaluate(ref SchemeAST currentAST) { var returnValue = new List<SchemeObject>(); if (currentAST.currentObject == SchemeVoid.instance) { for (int i = 0; i < currentAST.children.Count; i++) { var ast = (SchemeAST)currentAST.children[i]; int instructionCount = 0; while (true) { Logger.writeLine(String.Format("Instruction: {0}", instructionCount++)); if (Logger.enableConsoleLog || Logger.enableLogfile) { ast.createTreeOutput(); } if (updateToNextLevelChild(ref ast, this.currentEnvironment)) //this updates currentAST until the first AST object is found which contains leaf objects only { continue; } var evaluated = evaluateSchemeAST(ref ast, this.currentEnvironment); //evaluate the expression if (evaluated == null) { continue; } updateParent(ref ast, evaluated); //replace currentAST with result if (ast.parent.currentObject != SchemeVoid.instance) { ast = ast.parent; //ascend the tree again } else { returnValue.Add(evaluated); break; } } } } return returnValue; }
public SchemeAST parseStringWithPos(string input, string filename) { SchemeAST root = new SchemeAST(); SchemeAST currentParent = root; var tokens = tokenizeWithPos(input); SchemeAST newToken; for (int i = 0; i < tokens.Count; i++) { string token = tokens[i].token; if (token == "(") { var j = 1 + i; if (tokens[j].token == ")") //peek if void { newToken = new SchemeAST(currentParent, SchemeVoid.instance); currentParent.children.Add(newToken); newToken.sourceOffset = tokens[i].offset; newToken.sourceLength = tokens[i].length; i += 2; } var oldParent = currentParent; currentParent = new SchemeAST(oldParent, makeSchemeObject(tokens[++i].token)); //make new ast node and assign it to the parent. Also advance the counter! currentParent.sourceOffset = tokens[i].offset; currentParent.sourceLength = tokens[i].length; oldParent.children.Add(currentParent); } else if (token == ")") { currentParent = currentParent.parent; //jump up one level } else { currentParent.children.Add(new SchemeAST(currentParent, makeSchemeObject(token))); } } return root; }
private bool updateToNextLevelChild(ref SchemeAST currentAst, ISchemeEnvironment environment) { Type type = currentAst.currentObject.GetType(); if (type == typeof(SchemeSymbol)) { SchemeType t = environment.get((SchemeSymbol)currentAst.currentObject); if (t == null) { throw new SchemeUndefinedSymbolException(String.Format("Undefined Symbol: {0}", currentAst.currentObject.ToString()), currentAst.fileName, currentAst.sourceLength, currentAst.sourceOffset); } Type obj = t.GetType(); if (obj == typeof(SchemeBuiltInLambda)) // or typeof if. this is needed for parts which should not be evaluated. { return false; } if (obj == typeof(SchemeBuiltInIf)) { var tmpRoot = new SchemeAST(); var condition = currentAst.children[0]; var oldParent = condition.parent; tmpRoot.children.Add(condition); condition.parent = tmpRoot; var evaluated = evaluate(ref tmpRoot); //evaluate the if condition tmpRoot = new SchemeAST(currentAst, evaluated[0]); currentAst.children[0] = tmpRoot; return false; } } foreach (SchemeAST child in currentAst.children) { if (child.children.Count != 0) { currentAst = child; return true; } } return false; }
private void updateParent(ref SchemeAST currentAST, SchemeObject newValue) { /* if (currentAST.currentObject.GetType() == typeof(SchemeLambda)) { // foreach (SchemeType obj in currrentEn ) foreach (string key in currentEnvironment.getDict().Keys) { currentEnvironment.parent().set(new SchemeSymbol(key), currentEnvironment.getDict()[key]); } } */ if (currentAST.hasOwnEnviornment)// && currentEnvironment.parent() != null ) { /* if (newValue is SchemeLambda) { foreach (string key in currentEnvironment.getDict().Keys) { currentEnvironment.parent().set(new SchemeSymbol(key), currentEnvironment.getDict()[key]); } } */ currentEnvironment = currentEnvironment.parent(); } int postition = currentAST.parent.children.IndexOf(currentAST); currentAST.parent.children.Remove(currentAST); // if( newValue != SchemeVoid.instance ) // { var returnValue = new SchemeAST(currentAST.parent, newValue); currentAST.parent.children.Insert(postition, returnValue); // } }
private SchemeType getType(ref SchemeAST ast, ISchemeEnvironment environment) { SchemeObject ret = ast.currentObject; if (ast.currentObject.GetType() == typeof(SchemeSymbol)) { ret = environment.get((SchemeSymbol)ret); } if (!(ret is SchemeType)) { return null; } return (SchemeType)ret; }
private ISchemeFunction getFunction(ref SchemeAST ast, ISchemeEnvironment environment) { SchemeObject ret = ast.currentObject; if (ast.currentObject.GetType() == typeof(SchemeSymbol)) { ret = environment.get((SchemeSymbol)ret); } if (!(ret is ISchemeFunction)) { return null; } return (ISchemeFunction)ret; }
private SchemeObject evaluateSchemeAST(ref SchemeAST ast, ISchemeEnvironment environment) { var func = getFunction(ref ast, environment); if (func != null) { return func.evaluate(ref ast, this); } else { var type = getType(ref ast, environment); if (type != null) { return type; } else { throw new SchemeNoSuchMethodException(String.Format("{0} is no valid Scheme Method!", ast.currentObject.ToString())); } } }
public SchemeAST( SchemeAST parent, SchemeObject currentObject ) { // Debug.Assert( parent != null && currentObject != null ); _parent = parent; this.currentObject = currentObject; }
private void createTreeOutputHelper(string indent, bool last, SchemeAST caller) { Logger.write(indent); if (last) { Logger.write("\\-"); indent += " "; } else { Logger.write("|-"); indent += "| "; } if (currentObject.ToString() == "") { Logger.write("<void>"); } else { Logger.write(currentObject.ToString()); } if( System.Diagnostics.Debugger.IsAttached ) { treeSanityCheck(); } if (caller == this) { Logger.writeLine(" <---"); } else { Logger.write("\n"); } for (int i = 0; i < children.Count; i++) children[i].createTreeOutputHelper(indent, i == children.Count - 1, caller); }
public SchemeAST() { _parent = null; this.currentObject = SchemeVoid.instance; }
public void updateParent(SchemeAST newParent) { _parent = newParent; foreach (SchemeAST child in _children) { child.updateParent(this); } }