예제 #1
0
파일: Parser.cs 프로젝트: hww/VARP
        private static Syntax ParseVector(Token thisToken, Tokenizer moreTokens)
        {
            var   listContents = new List <object>();
            Token dotToken     = null;

            var nextToken = moreTokens.ReadToken();

            while (nextToken != null && nextToken.Type != TokenType.CloseBracket)
            {
                // Parse this token
                listContents.Add(ParseToken(nextToken, moreTokens));

                // Fetch the next token
                nextToken = moreTokens.ReadToken();
                if (nextToken == null)
                {
                    throw SchemeError.SyntaxError("parser", "Improperly formed list.", dotToken);
                }

                //if (!improper && nextToken.Type == TokenType.Symbol && dotSymbol.Equals(nextToken.Value) && thisToken.Type == TokenType.OpenBracket)
                if (nextToken.Type == TokenType.Dot)
                {
                    throw SchemeError.SyntaxError("parser", "Improperly formed dotted list", nextToken);
                }
            }

            if (nextToken == null) // Missing ')'
            {
                throw SchemeError.SyntaxError("parser", "Missing close parenthesis", thisToken);
            }

            return(new Syntax(ValueList.FromList(listContents), thisToken));
        }
예제 #2
0
        /// <summary>
        /// Make instruction of format A,B,C
        /// </summary>
        /// <param name="code"></param>
        /// <param name="a"></param>
        public static Instruction MakeABC(OpCode code, int a, int b, int c)
        {
            if (IsNotValueInRange(a, 0, AMask))
            {
                throw SchemeError.RangeError("Opcode.A.B.C", "Opcode", "A", a, code, 0, AMask);
            }

            if (IsNotValueInRange(b, 0, BMask))
            {
                throw SchemeError.RangeError("Opcode.A.B.C", "Opcode", "B", b, code, 0, BMask);
            }

            if (IsNotValueInRange(c, 0, CMask))
            {
                throw SchemeError.RangeError("Opcode.A.B.C", "Opcode", "C", c, code, 0, CMask);
            }

            var inst = new Instruction();

            inst.OpCode = code;
            inst.A      = a;
            inst.B      = b;
            inst.C      = c;
            return(inst);
        }
예제 #3
0
파일: BasePrimitive.cs 프로젝트: hww/VARP
 protected static void AssertArgsEqual(string name, string message, int expected, int given, LinkedList <Value> argv, Syntax expression)
 {
     if (given != expected)
     {
         throw SchemeError.ArityError(name, message, expected, given, argv, expression);
     }
 }
예제 #4
0
파일: Tokenizer.cs 프로젝트: hww/VARP
        // retrieve a quoted sugar token (' ` , ,@) and advance our position
        private Token QuoteSugar()
        {
            TokenType type;

            builder.Clear();

            switch (Character)
            {
            case '\'':
                type = TokenType.Quote;
                break;

            case '`':
                type = TokenType.QuasiQuote;
                break;

            case ',':
                type = TokenType.Unquote;
                break;

            default:
                throw SchemeError.SyntaxError("tokenizer", "unexpected character", lastToken);
            }

            builder.Append((char)Character);
            NextChar();
            if (Character == '@')
            {
                type = TokenType.UnquoteSplicing;
                NextChar();
                builder.Append((char)Character);
            }

            return(DefineToken(type, builder.ToString()));
        }
예제 #5
0
파일: ArgumentsParser.cs 프로젝트: hww/VARP
        /// <summary>
        /// Build argument pair from identifier and initializer only (lambda (:optional (x 1) (y 2) (z 3)) ...)
        /// </summary>
        private static void ParseArg(string name, Syntax stx, LinkedList <Value> list, Environment env, out Syntax id, out AST ast)
        {
            Debug.Assert(stx != null);
            Debug.Assert(list != null);
            Debug.Assert(env != null);
            var argc = list.Count;

            if (argc != 2)
            {
                throw SchemeError.ArityError("let", "lambda: bad &key or &optional argument", 2, argc, list, stx);
            }

            var a = list[0].AsSyntax();
            var b = list[1].AsSyntax();

            if (!a.IsIdentifier)
            {
                SchemeError.ArgumentError(name, "symbol?", a);
            }

            // compile initializer in the parent scope
            var exast = AstBuilder.ExpandInternal(b, env.Parent);

            id = a; ast = exast;
        }
예제 #6
0
파일: let.cs 프로젝트: hww/VARP
        // (let () ...)
        public static AST Expand(Syntax stx, Environment env)
        {
            var list = stx.AsLinkedList <Value>();
            var argc = GetArgsCount(list);

            AssertArgsMinimum("let", "arity mismatch", 2, argc, list, stx);

            var keyword   = list[0].AsSyntax();   // let arguments
            var arguments = list[1].AsSyntax();   // let arguments

            if (!arguments.IsExpression)
            {
                throw SchemeError.SyntaxError("let", "bad syntax (missing name or binding pairs)", stx);
            }

            var localEnv = ArgumentsParser.ParseLet(stx, arguments.AsLinkedList <Value>(), env);

            AST lambda = new AstLambda(stx, keyword, localEnv, AstBuilder.ExpandListElements(list, 2, localEnv));

            var result = new LinkedList <Value>();

            result.AddLast(lambda.ToValue());
            foreach (var v in localEnv)
            {
                if (v is ArgumentBinding)
                {
                    var arg = v as ArgumentBinding;
                    if (arg.ArgType == ArgumentBinding.Type.Required)
                    {
                        result.AddLast(new Value(arg.Initializer));
                    }
                }
            }
            return(new AstApplication(stx, result));
        }
예제 #7
0
파일: Syntax.cs 프로젝트: hww/VARP
 /// <summary>
 /// Get identifier (exception if syntax is not identifier)
 /// </summary>
 /// <returns></returns>
 public Symbol AsIdentifier()
 {
     if (expression.IsSymbol)
     {
         return(expression.AsSymbol());
     }
     throw SchemeError.ArgumentError("get-identifier", "identifier?", this);
 }
예제 #8
0
 public static string ToString(ValueType value)
 {
     Debug.Assert(value != null);
     if (value is NumericalType)
     {
         throw SchemeError.ErrorWithName("to-string", "can't inspect number-class", value);
     }
     return(value.ToString());
 }
예제 #9
0
        /// <summary>
        /// Set value from the C# value type as the argument
        /// is object reference then value is in the box.
        /// </summary>
        /// <param name="value"></param>
        private void SetFromValueType(object value)
        {
            // the quick check

            if (value is Value)
            {
                this = (Value)value;
            }

            // core types first

            else if (value is bool)
            {
                Set((bool)value);
            }
            else if (value is int)
            {
                Set((int)value);
            }
            else if (value is double)
            {
                Set((double)value);
            }

            //and now all the odd cases (note the leading else!)

            else if (value is uint)
            {
                Set((double)(uint)value);
            }
            else if (value is float)
            {
                Set((double)(float)value);
            }
            else if (value is sbyte)
            {
                Set((double)(sbyte)value);
            }
            else if (value is byte)
            {
                Set((double)(byte)value);
            }
            else if (value is short)
            {
                Set((double)(short)value);
            }
            else if (value is ushort)
            {
                Set((double)(ushort)value);
            }
            else
            {
                throw SchemeError.ErrorWithName("value-set", "can't assign the C# value-type", value);
            }
        }
예제 #10
0
파일: Syntax.cs 프로젝트: hww/VARP
        /// <summary>
        /// Method safely cast the syntax's expression to the Datum
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        private static Value GetDatum(Value expression)
        {
            if (expression.IsSyntax)
            {
                expression = (expression.AsSyntax()).expression;
            }

            if (expression.IsLinkedList <Value>())
            {
                var result = new LinkedList <Value>();
                foreach (var val in expression.AsLinkedList <Value>())
                {
                    result.AddLast(GetDatum(val));
                }
                return(new Value(result));
            }

            if (expression.IsLinkedList <Syntax>())
            {
                var src = expression.AsLinkedList <Syntax>();
                var dst = new LinkedList <Value>();
                foreach (var v in src)
                {
                    dst.AddLast(GetDatum(v.ToValue()));
                }
                return(new Value(dst));
            }

            if (expression.IsList <Value>())
            {
                var src = expression.AsList <Value>();
                var dst = new List <Value>(src.Count);
                foreach (var v in src)
                {
                    if (v.IsSyntax)
                    {
                        dst.Add(GetDatum(v.AsSyntax().ToValue()));
                    }
                    else
                    {
                        throw SchemeError.ArgumentError("syntax->datum", "identifier?", v);
                    }
                }
                return(new Value(dst));
            }

            if (expression.IsValuePair)
            {
                var pair = expression.AsValuePair();
                return(new Value(new ValuePair(GetDatum(pair.Item1), GetDatum(pair.Item2))));
            }

            return(expression);
        }
예제 #11
0
파일: ArgumentsParser.cs 프로젝트: hww/VARP
 /// <summary>
 /// Build argument pair from identifier only (lambda (:optional x y z) ...)
 /// </summary>
 private static void ParseArg(string name, Syntax stx, Syntax identifier, Environment env, out Syntax var)
 {
     Debug.Assert(stx != null);
     Debug.Assert(identifier != null);
     Debug.Assert(env != null);
     if (!identifier.IsIdentifier)
     {
         SchemeError.ArgumentError(name, "symbol?", identifier);
     }
     var = identifier;
 }
예제 #12
0
        /// <summary>
        /// Make instruction of format A
        /// </summary>
        /// <param name="code"></param>
        /// <param name="a"></param>
        public static Instruction MakeA(OpCode code, int a)
        {
            if (IsNotValueInRange(a, 0, AMask))
            {
                throw SchemeError.RangeError("Opcode.A", "Opcode", "A", a, code, 0, AMask);
            }

            var inst = new Instruction();

            inst.OpCode = code;
            inst.A      = a;
            return(inst);
        }
예제 #13
0
파일: Parser.cs 프로젝트: hww/VARP
        /// <summary>
        /// Turns thisToken into an object, using moreTokens to get further tokens if required
        /// </summary>
        /// <returns></returns>
        protected static Syntax ParseToken(Token thisToken, Tokenizer moreTokens)
        {
            if (thisToken == null)
            {
                throw SchemeError.SyntaxError("parser", "unexpectedly reached the end of the input", moreTokens.LastToken);
            }

            switch (thisToken.Type)
            {
            //case TokenType.Dot:
            //    return thisToken; //TODO maybe exception or symbol .

            case TokenType.Character:
                return(new Syntax(new Value(thisToken.GetCharacter()), thisToken));

            case TokenType.Boolean:
                return(new Syntax(new Value(thisToken.GetBool()), thisToken));

            case TokenType.String:
                return(new Syntax(new Value(thisToken.GetString()), thisToken));

            case TokenType.Symbol:
                return(new Syntax(thisToken.GetSymbol(), thisToken));

            case TokenType.Heximal:
            case TokenType.Integer:
                return(new Syntax(new Value(thisToken.GetInteger()), thisToken));

            case TokenType.Floating:
                return(new Syntax(new Value(thisToken.GetFloat()), thisToken));

            case TokenType.OpenBracket:
                return(ParseList(thisToken, moreTokens));

            case TokenType.OpenVector:
                return(ParseVector(thisToken, moreTokens));

            case TokenType.Quote:
            case TokenType.Unquote:
            case TokenType.UnquoteSplicing:
            case TokenType.QuasiQuote:
                return(ParseQuoted(thisToken, moreTokens));

            case TokenType.BadNumber:
                throw SchemeError.SyntaxError("parser", "looks like it should be a number, but it contains a syntax error", thisToken);

            default:
                // Unknown token type
                throw SchemeError.SyntaxError("parser", "the element is being used in a context where it is not understood", thisToken);
            }
        }
예제 #14
0
파일: Parser.cs 프로젝트: hww/VARP
        /// <summary>
        /// Parses a scheme expression in the default manner
        /// </summary>
        /// <returns>A scheme object</returns>
        /// <remarks>It is an error to pass scheme to this method with 'extraneous' tokens, such as trailing closing brackets</remarks>
        public static Syntax Parse(string scheme, string filepath)
        {
            var reader = new Tokenizer(new System.IO.StringReader(scheme), filepath);

            var res   = Parse(reader);
            var token = reader.ReadToken();

            if (token != null)
            {
                throw SchemeError.SyntaxError("parser", "found extra tokens after the end of a scheme expression", token);
            }

            return(res);
        }
예제 #15
0
        /// <summary>
        /// Define new definition.
        /// </summary>
        /// <param name="name">identifier</param>
        /// <param name="binding">binding</param>
        public int Define(Symbol name, AstBinding binding)
        {
            var variable = LookupLocal(name);

            if (variable != null)
            {
                throw SchemeError.SyntaxError("define", "environment already have key", binding.Id);
            }

            binding.environment = this;
            binding.VarIdx      = Bindings.Count;
            Bindings[name]      = binding;
            return(binding.VarIdx);
        }
예제 #16
0
파일: Codegen.cs 프로젝트: hww/VARP
        /// <summary>
        ///
        /// </summary>
        /// <param name="ast"></param>
        /// <param name="template"></param>
        /// <returns>return dummy value</returns>
        private int Generate(AST ast)
        {
            if (ast is AstLiteral)
            {
                return(GenerateLiteral(ast as AstLiteral));
            }

            if (ast is AstReference)
            {
                return(GenerateReference(ast as AstReference));
            }

            if (ast is AstSet)
            {
                return(GenerateSet(ast as AstSet));
            }

            if (ast is AstLambda)
            {
                return(GenerateLambda(ast as AstLambda));
            }

            if (ast is AstConditionIf)
            {
                return(GenerateConditionIf(ast as AstConditionIf));
            }

            if (ast is AstCondition)
            {
                return(GenerateCondition(ast as AstCondition));
            }

            if (ast is AstPrimitive)
            {
                return(GeneratePrimitive(ast as AstPrimitive));
            }

            if (ast is AstApplication)
            {
                return(GenerateApplication(ast as AstApplication));
            }

            if (ast is AstSequence)
            {
                return(GenerateSequence(ast as AstSequence));
            }

            throw SchemeError.ErrorWithName("codegen-generate", "unexpected ast", ast);
        }
예제 #17
0
 public char GetCharacter()
 {
     Debug.Assert(Type == TokenType.Character);
     if (Value.Length == 3)
     {
         return(System.Convert.ToChar(Value[2]));
     }
     else
     {
         var c = (char)0;
         if (CharType.NameToCharacter(Value, out c))
         {
             return(c);
         }
         throw SchemeError.SyntaxError("get-character", "improperly formed char value", this);
     }
 }
예제 #18
0
        public bool GetBool()
        {
            Debug.Assert(Type == TokenType.Boolean);

            if (Value == "#t")
            {
                return(true);
            }
            else if (Value == "#f")
            {
                return(false);
            }
            else
            {
                throw SchemeError.SyntaxError("get-bool", "improperly formed bool value", this);
            }
        }
예제 #19
0
        public int GetInteger()
        {
            try
            {
                switch (Type)
                {
                case TokenType.Integer:
                    return(StringLibs.GetInteger(Value));

                case TokenType.Heximal:
                    return(StringLibs.GetHexadecimal(Value));

                default:
                    throw SchemeError.SyntaxError("get-integer", "wrong token type", this);
                }
            }
            catch (System.Exception ex)
            {
                throw SchemeError.SyntaxError("get-integer", "improperly formed int value", this);
            }
        }
예제 #20
0
파일: Tokenizer.cs 프로젝트: hww/VARP
        // retrieve a string literal token and advance our position
        private Token StringLiteral()
        {
            builder.Clear();
            NextChar();
            var type = TokenType.String;

            var matchingQuotes = false;

            while (Character >= 0)
            {
                // if we get an escape, increment the position some more and map the escaped character to what it should be
                if (Character == '\\')
                {
                    NextChar();
                    builder.Append(MapEscaped(Character));
                    NextChar();
                    continue;
                }

                // unescaped quote? We're done with this string.
                if (Character == '"')
                {
                    NextChar();
                    matchingQuotes = true;
                    break;
                }

                builder.Append((char)Character);
                NextChar();
            }

            // we didn't get opening and closing quotes :(
            if (!matchingQuotes)
            {
                throw SchemeError.SyntaxError("tokenizer", "unmatched quotes in string literal", lastToken);
            }

            return(DefineToken(type, builder.ToString()));
        }
예제 #21
0
파일: ArgumentsParser.cs 프로젝트: hww/VARP
        private static AstBinding ParseOptional(string name, Syntax stx, Syntax definition, Environment env, ArgumentBinding.Type type)
        {
            Syntax var = null;
            AST    val = null;

            if (definition.IsIdentifier)
            {
                ParseArg(name, stx, definition, env, out var);
            }
            else if (definition.IsExpression)
            {
                ParseArg(name, stx, definition.AsLinkedList <Value>(), env, out var, out val);
            }
            else
            {
                throw SchemeError.ArgumentError("lambda", "list?", definition);
            }
            var binding = new ArgumentBinding(var, type, val);

            env.Define(binding);
            return(binding);
        }
예제 #22
0
파일: AstBuilder.cs 프로젝트: hww/VARP2
 // Expand string @syntax to abstract syntax tree, in given @env environment
 public static Ast ExpandInternal(Syntax syntax, Environment env)
 {
     if (syntax == null)
     {
         return(null);
     }
     else if (syntax.IsLiteral)
     {
         return(ExpandLiteral(syntax, env));
     }
     else if (syntax.IsIdentifier)
     {
         return(ExpandIdentifier(syntax, env));
     }
     else if (syntax.IsExpression)
     {
         return(ExpandExpression(syntax, env));
     }
     else
     {
         throw SchemeError.SyntaxError("ast-builder-expand", "expected literal, identifier or list expression", syntax);
     }
 }