private void VisitRestOfList(AstList ast) { for (var i = 1; i < ast.Length; i++) { Visit(ast[i]); } }
private void GenerateQuote(AstList ast) { AddInstr(new ListNewInstruction()); if (ast.Length != 2) { throw new InvalidOperationException("Unexpected length for quote function"); } var datum = ast[1]; switch (datum) { case AstList list: for (var i = 0; i < list.Length; i++) { Visit(list[i]); AddInstr(new ListAddInstruction()); } break; default: Visit(datum); break; } }
void IAstVisitor.VisitList(AstList ast) { if (ast.Length == 0) { return; } var first = (AstSymbol)ast[0]; switch (first.Name) { case "def!": DefineMethod(ast); break; case "add": case "+": VisitRestOfList(ast); AddInstr(new AddInstruction()); break; case "sub": case "-": VisitRestOfList(ast); AddInstr(new SubtractionInstruction()); break; case "mul": case "*": VisitRestOfList(ast); AddInstr(new MultiplicationInstruction()); break; case "div": case "/": VisitRestOfList(ast); AddInstr(new DivisionInstruction()); break; case "quote": GenerateQuote(ast); break; default: VisitRestOfList(ast); AddInstr(new CallInstruction(first.Name)); break; } }
void IAstVisitor.VisitList(AstList ast) { if (ast.Length == 0) { return; } var first = (AstSymbol)ast[0]; switch (first.Name) { case "def!": DefineMethod(ast); break; } }
private void DefineMethod(AstList ast) { if (ast.Length < 3) { throw new InvalidOperationException("Too few list parameters"); } var nameSymbol = ast[1]; if (nameSymbol is AstSymbol s) { this.userDefinedFunctions[s.Name] = new VMFunction(s.Name, Eval(ast[2], new ReturnInstruction())); } else { throw new InvalidOperationException($"Expected to find symbol at index 1"); } }
private void DefineMethod(AstList ast) { if (ast.Length < 3) { throw new InvalidOperationException("Too few list parameters"); } var nameSymbol = ast[1]; if (nameSymbol is AstSymbol s) { this.data.Defines[s] = Eval(ast[2]); } else { throw new InvalidOperationException($"Expected to find symbol at index 1"); } }
private IAstNode?ParseList() { if (IsToken(LispTokenKind.Quote)) { AdvanceToken(LispTokenKind.Quote); var quotedNode = ParseList(); if (quotedNode is AstList quotedList) { var resultList = new AstList(); resultList.Add(new AstSymbol("quote")); resultList.Add(quotedList); return(resultList); } else { throw new NotImplementedException("After quotation expected to have a list"); } } if (!IsToken(LispTokenKind.LParen)) { return(null); // TODO: Maybe figure out how to not use null value as return //throw new InvalidOperationException("Expression should start with LParen"); } AdvanceToken(LispTokenKind.LParen); var astList = new AstList(); while (!IsToken(LispTokenKind.RParen)) { astList.Add(ParseAtom()); } AdvanceToken(LispTokenKind.RParen); return(astList); }