public static (Value, bool)? Apply(OsmiumEngine engine, ExpressionValue expr)
        {
            if (expr.Head is ExpressionValue hexpr)
            {
                if (hexpr.Head is Symbol sv && sv == engine.System.Apply && hexpr.Count == 1 && expr.Count == 1)
                {
                    return(DoApply(engine, hexpr[0], expr[0], 0, 0), true);
                }
            }
            else if (expr.Head is Symbol sv && sv == engine.System.Apply)
            {
                if (expr.Count == 1)
                {
                    return(null);
                }

                if (expr.Count == 2)
                {
                    return(DoApply(engine, expr[0], expr[1], 0, 0), true);
                }

                // TODO levelspec
            }

            return(null);
        }
        public static (Value, bool)? Append(OsmiumEngine engine, ExpressionValue expr)
        {
            if (!expr.Head.Equals(engine.System.Append))
            {
                return(null);
            }
            if (expr.Count != 2)
            {
                // TODO: message
                return(null);
            }

            var list     = expr[0];
            var toAppend = expr[1];

            if (list is ExpressionValue e)
            {
                var newParts = new Value[e.Count + 1];
                Array.Copy(e.Parts.ToArray(), newParts, e.Count);
                newParts[e.Count] = toAppend;

                return(engine.Expr(e.Head, newParts), true);
            }

            return(null);
        }
Esempio n. 3
0
 public void Setup()
 {
     _engine       = new OsmiumEngine();
     _blank        = _engine.Expr(_engine.Sym("System`Blank"));
     _blankSeq     = _engine.Expr(_engine.Sym("System`BlankSequence"));
     _blankNullSeq = _engine.Expr(_engine.Sym("System`BlankNullSequence"));
 }
Esempio n. 4
0
        public ExpressionValue(OsmiumEngine engine, Value head, params Value[] parts) : base(engine)
        {
            Head  = head ?? throw new ArgumentNullException(nameof(head));
            Parts = parts ?? throw new ArgumentNullException(nameof(parts));

            AtomHead = Head.AtomHead;
        }
Esempio n. 5
0
        public static Value Parse(OsmiumEngine engine, string input)
        {
            var lines = input.Split('\n');
            var lex   = new WolframLanguageLexer(new AntlrInputStream(input));
            var parse = new WolframLanguageParser(new CommonTokenStream(lex, Lexer.DefaultTokenChannel));

            lex.Parser = parse;
            var listen = new ExprBuildListener(engine, parse);

            var errors = new List <string>();

            parse.AddErrorListener(new ErrorListener <IToken>((recognizer, token, line, pos, msg, e) => { errors.Add($"Unexpected {token} at {line}:{pos}: {msg}"); }));
            var expr = parse.expr();

            ParseTreeWalker.Default.Walk(listen, expr);

            if (errors.Any())
            {
                foreach (var i in errors)
                {
                    Console.WriteLine("err: {0}", i);
                }
                return(null);
            }

            return(listen.GetValue());
        }
Esempio n. 6
0
        public static (Value, bool)? SetDelayed(OsmiumEngine engine, ExpressionValue expr)
        {
            if (expr.Count != 2)
            {
                // TODO: message
            }

            var lhs = expr[0];
            var rhs = expr[1];

            switch (lhs)
            {
            case ExpressionValue lhsExpr:
                // TODO: make sure head is a symbol
                DoSet(engine.PatternMatching.CompilePattern(lhsExpr), lhsExpr.SymbolHead, lhsExpr.SymbolHead.DownValues, rhs);
                break;

            case Symbol lhsSymbol:
                DoSet(engine.PatternMatching.CompilePattern(lhsSymbol), lhsSymbol, lhsSymbol.OwnValues, rhs);
                break;

            default:
                // TODO: message
                break;
            }

            return(engine.System.Null, false);
        }
 private static Value DoApply(OsmiumEngine engine, Value f, Value target, int lvlFrom, int lvlTo)
 {
     if (target is ExpressionValue expr)
     {
         return(engine.Expr(f, expr.Parts.ToArray()));
     }
     return(target);
 }
        public static (Value, bool)? Plus(OsmiumEngine engine, ExpressionValue value)
        {
            if (!(value.Head is Symbol sv) || sv != engine.System.Plus)
            {
                return(null);
            }

            return(NumericOp(engine, value, engine.Zero, NumericOperations.Add));
        }
Esempio n. 9
0
        private static Value ApplyIfDefined(OsmiumEngine engine, Symbol sym, Value value)
        {
            if (engine.System.SPreRead.HasOwnValue())
            {
                value = engine.Evaluate(engine.Expr(sym, value));
            }

            return(value);
        }
Esempio n. 10
0
        private static (Value, bool)? NumericOp(OsmiumEngine engine, ExpressionValue value, NumberValue identity, NumericOperations.NumericFunction op)
        {
            NumberValue nv = null;

            int numCount = 0;

            var nonNum = new List <Value>();

            foreach (var part in value)
            {
                if (!(part is NumberValue numPart))
                {
                    nonNum.Add(part);
                    continue;
                }

                numCount++;

                nv = nv == null ? numPart : op(nv, numPart);
            }

            if (nonNum.Count == 0) // there were no non-numbers ( 1 + 2 ) -> 3
            {
                return(nv, true);
            }

            if (nv == null) //  no number was found (x + y)
            {
                return(value, false);
            }

            if (nv.Equals(identity))   // total of numbers was the identity element ( x + y + 1 - 1 ) -> ( x + y )
            {
                if (nonNum.Count == 1) // exactly one non-number ( x + 1 - 1 ) -> x
                {
                    return(nonNum[0], true);
                }

                // multiple non-numbers, keep the Plus head
                return(engine.Expr(value.Head, nonNum.ToArray()), true);
            }

            if (numCount == 1) // there was exactly one number, nothing changed  (x + 1) -> (x + 1)
            {
                return(value, false);
            }

            // there were multiple numbers, add the result and keep the rest (x + y + 1 + 2) -> (x + y + 3)
            nonNum.Add(nv);
            return(engine.Expr(value.Head, nonNum.ToArray()), true);
        }
Esempio n. 11
0
        public static (Value, bool)? Times(OsmiumEngine engine, ExpressionValue value)
        {
            if (!(value.Head is Symbol sv) || sv != engine.System.Times)
            {
                return(null);
            }

            if (value.Count == 2 && value[0].Equals(engine.MinusOne) && value[1] is NumberValue number)
            {
                return(number.Neg(), true);  // short-circuit form for Times[-1, x]
            }

            return(NumericOp(engine, value, engine.Zero, NumericOperations.Mul));
        }
Esempio n. 12
0
        public RationalValue(OsmiumEngine engine, BigInteger numerator, BigInteger denominator) : base(engine)
        {
            if (denominator.Sign < 0)
            {
                numerator   = -numerator;
                denominator = -denominator;
            }

            var gcd = GCD(numerator, denominator);

            if (gcd != 1)
            {
                numerator   /= gcd;
                denominator /= gcd;
            }
            Numerator   = numerator;
            Denominator = denominator;
        }
        public static (Value, bool)? And(OsmiumEngine engine, ExpressionValue expr)
        {
            var pts = new List <Value>();

            bool noChange = true;

            foreach (var part in expr.Parts)
            {
                var epart = engine.Evaluate(part);
                if (epart is Symbol sv)
                {
                    if (sv == engine.System.False)
                    {
                        return(epart, false);
                    }

                    if (sv == engine.System.True)
                    {
                        continue;
                    }
                }

                noChange = noChange && epart.Equals(part);

                pts.Add(epart);
            }

            if (pts.Count == 0)
            {
                return(engine.System.True, false);
            }

            if (pts.Count == 1)
            {
                return(pts[0], false);
            }

            return(engine.Expr(engine.System.And,
                               pts.ToArray()
                               ), false);
        }
Esempio n. 14
0
 private static void AddDownValue(OsmiumEngine engine, Symbol sym, Value value, params Value[] args)
 {
     sym.DownValues.Append((engine.PatternMatching.CompilePattern(engine.Expr(sym, args)), value));
 }
Esempio n. 15
0
        static void Main(string[] args)
        {
            var prompt = true;

            if (prompt)
            {
                Console.WriteLine("Osmium Kernel");
            }

            var engine = new OsmiumEngine();

            while (true)
            {
                if (!engine.System.SLine.HasOwnValue())
                {
                    // $Line = 1
                    engine.Set(engine.System.SLine, engine.One);
                }

                if (prompt)
                {
                    Console.WriteLine();
                    Console.Write("In[{0}]:= ", engine.System.SLine.GetValue());
                }

                var input = Console.ReadLine();

                input = (ApplyIfDefined(engine, engine.System.SPreRead, engine.Str(input)) as StringValue)?.Value ?? "";

                var parsed = engine.Parse(input);

                if (parsed == null)
                {
                    continue;
                }

                AddDownValue(engine, engine.System.InString, engine.Str(input), engine.System.SLine);
                AddDownValue(engine, engine.System.In, parsed, engine.System.SLine);

                var output = engine.Evaluate(engine.System.SPre.HasOwnValue() ? engine.Expr(engine.System.SPre, parsed) : parsed);

                output = ApplyIfDefined(engine, engine.System.SPost, output);

                AddDownValue(engine, engine.System.Out, output);

                engine.SetDelayed(
                    engine.Expr(engine.System.MessageList, engine.System.SLine),
                    engine.System.SMessageList.HasOwnValue() ? engine.System.SMessageList.GetValue() : engine.List()
                    );

                if (!output.Equals(engine.Null))
                {
                    output = ApplyIfDefined(engine, engine.System.SPrePrint, output);

                    if (prompt)
                    {
                        Console.WriteLine();
                        Console.WriteLine("Out[{0}]= {1}", engine.System.SLine.GetValue(), output);
                    }
                    else
                    {
                        Console.WriteLine(output);
                    }
                }

                engine.Evaluate(engine.Expr(engine.System.Increment, engine.System.SLine));
            }
        }
Esempio n. 16
0
 public ExprPattern(OsmiumEngine engine, Pattern head, Pattern[] parts)
 {
     _engine = engine;
     _head   = head;
     _parts  = parts;
 }
Esempio n. 17
0
 public PatternMatching(OsmiumEngine engine)
 {
     _engine = engine;
 }
Esempio n. 18
0
 public RealValue(OsmiumEngine engine, double value) : base(engine)
 {
     Value = value;
 }
Esempio n. 19
0
 public IntegerValue(OsmiumEngine engine, BigInteger value) : base(engine)
 {
     Value = value;
 }
Esempio n. 20
0
 protected Value(OsmiumEngine engine)
 {
     Engine = engine;
 }
Esempio n. 21
0
 public ComplexValue(OsmiumEngine engine, NumberValue real = null, NumberValue complex = null) : base(engine)
 {
     Real = real ?? Engine.Zero;
     Imag = complex ?? Engine.Zero;
 }
Esempio n. 22
0
 public void SetUp()
 {
     _e = new OsmiumEngine();
 }
Esempio n. 23
0
 protected AtomicValue(OsmiumEngine engine) : base(engine)
 {
 }
Esempio n. 24
0
 public Evaluator(OsmiumEngine engine)
 {
     _engine = engine;
 }
Esempio n. 25
0
 public ExprBuildListener(OsmiumEngine engine, WolframLanguageParser parse)
 {
     _engine = engine;
     _parse  = parse;
 }
Esempio n. 26
0
 public StringValue(OsmiumEngine engine, string value) : base(engine)
 {
     Value = value ?? throw new ArgumentNullException(nameof(value));
 }
Esempio n. 27
0
 private RationalValue(OsmiumEngine engine, BigInteger numerator, BigInteger denominator, bool unused) : base(engine)
 {
     Numerator   = numerator;
     Denominator = denominator;
 }
Esempio n. 28
0
 protected NumberValue(OsmiumEngine engine) : base(engine)
 {
 }