Пример #1
0
 private void VisitRestOfList(AstList ast)
 {
     for (var i = 1; i < ast.Length; i++)
     {
         Visit(ast[i]);
     }
 }
Пример #2
0
        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;
            }
        }
Пример #3
0
        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;
            }
        }
Пример #4
0
        void IAstVisitor.VisitList(AstList ast)
        {
            if (ast.Length == 0)
            {
                return;
            }

            var first = (AstSymbol)ast[0];

            switch (first.Name)
            {
            case "def!":
                DefineMethod(ast);
                break;
            }
        }
Пример #5
0
        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");
            }
        }
Пример #6
0
        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");
            }
        }
Пример #7
0
        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);
        }