adder-script
Version:
Python like language to execute untrusted codes in browsers and Node.js.
404 lines (350 loc) • 13.8 kB
HTML
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Adder Sandbox</title>
<!-- include AdderScript -->
<script src="../dist/adder.js"></script>
<!-- jquery and bootstrap css -->
<script type="text/javascript" src="../tests/libs/jquery.min.js"></script>
<script type="text/javascript" src="../tests/libs/bootstrap.min.js"></script>
<link href="../tests/libs/bootstrap.min.css" rel="stylesheet">
<!-- code mirror -->
<script src="../tests/libs/codemirror.js" type="text/javascript"></script>
<script src="../tests/libs/show-hint.js" type="text/javascript"></script>
<script src="../codemirror/adder.js" type="text/javascript"></script>
<script src="../tests/libs/matchbrackets.js" type="text/javascript"></script>
<link href="../tests/libs/codemirror.css" rel="stylesheet">
<link href="../tests/libs/show-hint.css" rel="stylesheet">
<!-- favicon -->
<link rel="icon" href="./../img/AdderIcon-xs.png">
<style>
body {
padding: 10px 10px 10px 10px;
overflow-x: hidden;
height: 100%;
}
html {
height: 100%;
}
#content, .container-fluid
{
overflow-y:auto;
height:100%;
}
button {
margin-bottom: 1px ;
}
#output p {
margin: 0;
word-wrap: break-word;
}
</style>
</head>
<body>
<div class="container-fluid">
<!-- top half - code box and options -->
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<h2 style="margin-top:0;"><img src="./../img/logo-sm.png" height="60px" > <span style="top: 10px;position: relative;">Sandbox</span></h2>
<!-- code box -->
<div class="col-md-10 col-sm-10 col-xs-9">
<div style="border: 1px solid black; padding: 0px; height:100%">
<textarea id="code" cols="100" rows="26">print("Hello World!")</textarea>
</div>
</div>
<!-- menu buttons -->
<div class="col-md-2 col-sm-2 col-xs-3">
<button type="button" onclick="window.evaluateCurrCode();" class="btn btn-primary btn-lg" style="width:100%">Execute</button>
<a href="http://adderscript.com/" target="_blank"><button type="button" class="btn btn-info" style="width:100%">Read Docs</button></a>
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#examplesModal" style="width:100%">Examples</button>
<button type="button" onclick="clearContext();" class="btn btn-warning" style="width:100%">Clear Context</button>
<button type="button" onclick="clearCode();" class="btn btn-danger" style="width:100%">New Code</button>
<div class="checkbox">
<label><input id="exec-on-change" type="checkbox" value="" checked>Execute On Change</label>
</div>
<div class="checkbox">
<label><input id="clear-context" type="checkbox" value="" checked>Clear global variables between runs</label>
</div>
</div>
</div>
</div>
<!-- bottom half - output and context data -->
<div class="row" style="height:40%">
<div class="col-md-12 col-sm-12 col-xs-12">
<h2>Output:</h2>
<!-- output box -->
<div class="col-md-9 col-sm-9 col-xs-9">
<div style="border: 1px solid black;">
<div id="output" style="width:100%; height:13.2em; overflow-y: scroll; padding: 10px 10px 10px 10px;"></div>
</div>
</div>
<!-- global scope data -->
<div class="col-md-3 col-sm-3 col-xs-3">
<label for="global-scope">Global Scope:</label>
<select class="form-control" onchange="showCurrVarValue();" id="global-scope" size="6">
</select>
<span>Selected Value: </span><input readonly id="curr-var-val" style="width:100%">
</div>
</div>
</div>
<!-- Examples form -->
<div id="examplesModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Adder Examples</h4>
</div>
<div class="modal-body">
<p>Choose an example program to show (will replace current code):</p>
<button type="button" onclick="setExample('hello-world');" class="btn btn-default" style="width:100%">Hello World</button>
<button type="button" onclick="setExample('fibonacci');" class="btn btn-default" style="width:100%">Fibonacci</button>
<button type="button" onclick="setExample('prime-numbers');" class="btn btn-default" style="width:100%">Prime Numbers</button>
<button type="button" onclick="setExample('hanoi');" class="btn btn-default" style="width:100%">Hanoi Towers</button>
<button type="button" onclick="setExample('factorial');" class="btn btn-default" style="width:100%">Factorial</button>
<button type="button" onclick="setExample('pascal-triangle');" class="btn btn-default" style="width:100%">Pascal Triangle</button>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<!-- init code mirror -->
<script type="text/javascript">
CodeMirror.commands.autocomplete = function(cm) {
cm.showHint();
}
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
lineNumbers: true,
textWrapping: false,
indentUnit: 4,
parserConfig: {'pythonVersion': 2, 'strictErrors': true},
extraKeys: {"Ctrl-Space": "autocomplete"},
});
</script>
<!-- function to handle print output -->
<script>
// print output
function printOutput()
{
addOutput(AdderScript.Utils.toArray(arguments).join(" "));
}
// clear current output
function clearOutput() {
$("#output")[0].innerHTML = "";
}
// add output to output div
function addOutput(txt, color) {
// fix spaces
txt = txt.replace(/\s/g, "\u00a0");
// default color
color = color || "blue";
// create the new line
var newLine = $("<p class='ret-val' style='color:" + color + "'></p>");
newLine.text(txt);
$("#output").append(newLine);
// scroll all the way down
$('#output').scrollTop($('#output')[0].scrollHeight);
}
</script>
<!-- clear current code completely + context -->
<script>
function clearCode() {
clearOutput();
editor.setValue("");
editor.clearHistory();
initNewAdder();
}
</script>
<!-- init environment and program -->
<script>
// function to init new adder environment and program (clears previous context)
function initNewAdder(skipUpdateGlobalScope)
{
// init adder script
window.AdderScript.init({
flags: {},
modules: ["ALL"],
outputFunc: printOutput,
showDebugConsole: true,
});
// spawn a program
window.program = window.AdderScript.newProgram();
// update global scope show
if (!skipUpdateGlobalScope) updateGlobalScopeShow();
}
// init first time
initNewAdder(true);
// clear context
function clearContext() {
initNewAdder(false);
}
</script>
<!-- show the value of the current global var selected -->
<script>
function showCurrVarValue() {
var key = $('#global-scope').find(":selected").text();
value = program.getGlobalVar(key);
$("#curr-var-val").val(String(value));
}
</script>
<!-- function to evaluate current code and show output -->
<script>
// evaluate current code and add exceptions to output
function evaluateCurrCode() {
// if requested to clear context
if ($("#clear-context").is(":checked")) {
clearContext(false);
}
// clear output
clearOutput();
// get code
var code = editor.getValue();
// try to evaluate and catch unhandled errors
try {
program.evalRawCode(code);
program.propagateExecutionErrors();
} catch(e) {
addOutput(e.message, "red");
}
// update global scope list
updateGlobalScopeShow();
}
// update global scope show
function updateGlobalScopeShow() {
// first clear it
$('#global-scope')
.find('option')
.remove();
// now get all var names and add them
var names = program.getGlobalScopeVarNames();
names.sort();
for (var i = 0; i < names.length; ++i) {
$('#global-scope').append($("<option>" + names[i] + "</option>"));
}
// clear current value show
$("#curr-var-val").val("");
}
// evaluate code on init
evaluateCurrCode();
</script>
<!-- on code change -->
<script>
// register on-change handler
editor.on('change',function(cMirror){
// if the option to execute on every change is set, evaluate current code
if ($("#exec-on-change").is(":checked")) {
evaluateCurrCode();
}
});
</script>
<!-- set example code -->
<script>
function setExample(key) {
editor.setValue(examples[key]);
editor.clearHistory();
initNewAdder();
evaluateCurrCode();
}
</script>
<!-- example codes -->
<script>
// create examples dictionary
var examples = {};
// hello world
examples["hello-world"] = '\n\
# This will print "Hello World!" on the screen. \n\
print("Hello World!")\n\
';
// fibonacci example
examples["fibonacci"] = '\n\
# Example 1: Using looping technique \n\
def fib(n): \n\
a = 1\n\
b = 1\n\
for i in range(n-1): \n\
_a = a \n\
a = b \n\
b = _a + b \n\
return a \n\
print ("Fibonacci to 10 using loops: " + fib(10)) \n\
\n\
# Example 2: Using recursion \n\
def fibR(n): \n\
if n==1 or n==2: \n\
return 1 \n\
return fibR(n-1)+fibR(n-2) \n\
print ("Fibonacci to 10 using recursion: " + fibR(10)) \n\
';
examples["prime-numbers"] = '\n\
# This example will print all prime numbers from 1 to 100.\n\
\n\
# first create the list to return \n\
ret = list() \n\
\n\
# iterate numbers from 1 to 100 \n\
for num in range(1, 100):\n\
\n\
# calculate if number is prime\n\
is_prime = True\n\
for i in range(2,num):\n\
if num % i == 0:\n\
is_prime = False\n\
break\n\
\n\
# if number is prime add to return list\n\
if is_prime:\n\
ret.append(num)\n\
\n\
# print the return list \n\
print(ret) \n\
';
examples["hanoi"] = '\n\
# This example implements a simple recursive solution to Hanoi towers problem. \n\
def moveTower(height,fromPole, toPole, withPole): \n\
if height >= 1: \n\
moveTower(height-1,fromPole,withPole,toPole) \n\
moveDisk(fromPole,toPole) \n\
moveTower(height-1,withPole,toPole,fromPole) \n\
\n\
def moveDisk(fp,tp): \n\
print("moving disk from",fp,"to",tp) \n\
\n\
moveTower(3,"A","B","C") \n\
';
examples["factorial"] = '\n\
# will calculate and print factorial values from 1 to n \n\
def factorial(n): \n\
if n < 1: \n\
return 1 \n\
else: \n\
returnNumber = n * factorial(n - 1) \n\
print(str(n) + "! = " + str(returnNumber)) \n\
return returnNumber \n\
\n\
# print factorials from 1 to 10 \n\
factorial(10) \n\
';
examples["pascal-triangle"] = '\n\
# print pascal triangle with given size \n\
def pascal_triangle(rows): \n\
for rownum in range(rows): \n\
newValue = 1 \n\
PrintingList = list(newValue) \n\
for iteration in range (rownum): \n\
newValue = newValue * ( rownum-iteration ) * 1 / ( iteration + 1 ) \n\
PrintingList.append(int(newValue)) \n\
print(PrintingList) \n\
print() \n\
\n\
# print pascal triangle at the size of 10 \n\
pascal_triangle(5) \n\
';
</script>
</body>
</html>