blob: 2c45971ea4e97706b369c098ed6429ca9a14ab52 [file] [log] [blame]
/*
* Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
"use strict";
class State {
constructor(program)
{
this.values = new CaselessMap();
this.stringValues = new CaselessMap();
this.sideState = new WeakMap();
this.statement = null;
this.nextLineNumber = 0;
this.subStack = [];
this.dataIndex = 0;
this.program = program;
this.rng = createRNGWithFixedSeed();
let addNative = (name, callback) => {
this.values.set(name, new NativeFunction(callback));
};
addNative("abs", x => Math.abs(x));
addNative("atn", x => Math.atan(x));
addNative("cos", x => Math.cos(x));
addNative("exp", x => Math.exp(x));
addNative("int", x => Math.floor(x));
addNative("log", x => Math.log(x));
addNative("rnd", () => this.rng());
addNative("sgn", x => Math.sign(x));
addNative("sin", x => Math.sin(x));
addNative("sqr", x => Math.sqrt(x));
addNative("tan", x => Math.tan(x));
}
getValue(name, numParameters)
{
if (this.values.has(name))
return this.values.get(name);
let result;
if (numParameters == 0)
result = new NumberValue();
else {
let dim = [];
while (numParameters--)
dim.push(11);
result = new NumberArray(dim);
}
this.values.set(name, result);
return result;
}
getSideState(key)
{
if (!this.sideState.has(key)) {
let result = {};
this.sideState.set(key, result);
return result;
}
return this.sideState.get(key);
}
abort(text)
{
if (!this.statement)
throw new Error("At beginning of execution: " + text);
throw new Error("At " + this.statement.sourceLineNumber + ": " + text);
}
validate(predicate, text)
{
if (!predicate)
this.abort(text);
}
}