<!DOCTYPE HTML>
<HTML LANG="ja">
<HEAD>
<META CHARSET="Shift_JIS">
<TITLE>今どきの Tiny BASIC</TITLE>
</HEAD>
<BODY STYLE="background-color:#CCFFFF; user-select:none">
<DIV STYLE="text-align:center">
<BR>
<B><SPAN STYLE="color:#CC0000">今どきの Tiny BASIC</SPAN></B>
<DIV ID="scr" TABINDEX="0" STYLE="width:80ch; margin-left:auto; margin-right:auto; text-align:left; color:white; background-color:black; border:solid 4px black; font-family:monospace; font-size:large; outline:none">
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
<SPAN NAME="scr"></SPAN><BR>
</DIV>
<BR>
<BUTTON TYPE=BUTTON ID="load" onClick="load_source()">ロード</BUTTON>
<SPAN STYLE="margin-left:4em">改行:</SPAN>
<SELECT ID="le">
<OPTION>LF
<OPTION>CR
<OPTION>CR+LF
</SELECT>
<BUTTON TYPE=BUTTON ID="save" onClick="save_source()" STYLE="margin-left:0.5em">セーブ</BUTTON>
<BR>
</DIV>
<SCRIPT TYPE="text/javascript">
<!--
// Tiny BASIC インタープリタ
// このプログラムは Li-Chen Wang さん作の Palo Alto Tiny BASIC を基にしています.
// この JavaScript 版は馬渕 義彦が作りました.
function load_source() {
elem_file.value = "";
elem_file.click();
elem_scr.focus();
}
function load_source2() {
elem_load.disabled = elem_save.disabled = true;
prog.length = 0; // クリア
elem_dl.download = "untitled.bas";
file_reader = new FileReader();
file_reader.onloadend = load_source4;
file_reader.onload = load_source3;
file_reader.readAsText(elem_file.files.item(0), "US-ASCII");
}
function load_source3() {
var source = file_reader.result.split(/\n|\r|\r\n/);
var last_num = 0;
for(var i = 0; i < source.length; i++) {
var w = source[i].match(/^ *(\d*) *(.*)/);
if(!w[1].length) {
if(w[2].length) {
alert("行番号がありません。");
break;
}
continue;
}
var num = parseInt(w[1], 10)
if(num > 32767) {
alert("行番号が範囲外です。");
break;
}
if(num <= last_num) {
alert("行番号が順番に並んでいません。");
break;
}
if(w[2].length) {
prog.push({num:num, text:w[2]});
last_num = num;
}
}
elem_dl.download = elem_file.files.item(0).name;
restart(true);
}
function load_source4() {
file_reader = undefined;
elem_load.disabled = elem_save.disabled = false;
}
function save_source() {
var le;
switch(elem_le.selectedIndex) { // 改行
case 1: // CR
le = "\r";
break;
case 2: // CR+LF
le = "\r\n";
break;
default: // LF
le = "\n";
}
var source = "";
for(var line of prog)
source += line.num.toString().padStart(4, " ") + " " + line.text + le;
elem_dl.href = "data:text/plain;charset=US-ASCII;base64," + btoa(source);
elem_dl.click();
elem_scr.focus();
}
function scr_focus() {
if(!scr_focused) {
scr_focused = true;
refresh(cur_y);
}
}
function scr_blur() {
if(scr_focused) {
scr_focused = false;
refresh(cur_y);
}
}
function keydown(e) {
if(!scr_focused)
return true;
if(e.key == "Tab")
return true;
if(e.ctrlKey) { // Ctrl
switch(e.key) {
case "C": // Ctrl-C
case "c":
if(i_current < 0 && !list || input) { // LIST 以外のダイレクト モード または INPUT
if(to_id != undefined) {
clearTimeout(to_id);
to_id = undefined;
}
restart(true);
}
else {
brk = true;
}
break;
}
return false;
}
if(e.metaKey) // Meta
return false;
if(i_current < 0 && !list || input) { // LIST 以外のダイレクト モード または INPUT
switch(e.key) {
case "Backspace":
if(buffer.length) {
putstr("\b");
buffer = buffer.slice(0, -1);
}
return false;
case "Enter":
putstr("\r");
if(input) // INPUT
com_input3();
else
edit_direct();
return false;
}
if(e.key.length > 1 || e.key < " " || e.key > "~")
return false;
if(buffer.length < 132) {
putstr(e.key);
buffer += e.key;
}
}
return false;
}
function mouseup(e) {
if(e.target === elem_load || e.target === elem_le || e.target === elem_save
|| e.target.parentElement === elem_le)
return;
if(!scr_focused)
elem_scr.focus();
}
// 画面に文字列を出力する
function putstr(str) {
for(var c of str)
putc(c);
// 画面更新
for(var y = 0; y < 25; y++) {
if(scrmod[y])
refresh(y);
}
}
function putc(c) {
switch(c) {
case "\b": // Back Space
if(cur_x) {
scrbuf[cur_y] = scrbuf[cur_y].slice(0, -1);
cur_x--;
scrmod[cur_y] = true;
}
else {
if(cur_y) {
cur_y--;
scrbuf[cur_y] = (scrbuf[cur_y].length == 80)
? scrbuf[cur_y].substr(0, 79) : scrbuf[cur_y].padEnd(79, " ");
cur_x = 79;
scrmod[cur_y] = scrmod[cur_y + 1] = true;
}
}
break;
case "\t": // Tab
for(; ; ) {
putc(" ");
if(!(cur_x % 8))
break;
}
break;
case "\f": // Form Feed
scrbuf.fill("");
scrmod.fill(true);
cur_x = cur_y = 0;
break;
default:
if(c == "\r")
cur_x = 79;
else
scrbuf[cur_y] += c;
if(cur_x == 79) {
cur_x = 0;
if(cur_y == 24) {
// スクロール
scrbuf.shift();
scrbuf.push("");
scrmod.fill(true);
}
else {
cur_y++;
scrmod[cur_y - 1] = scrmod[cur_y] = true;
}
}
else {
cur_x++;
scrmod[cur_y] = true;
}
}
}
// 画面更新
function refresh(y) {
var scr = scrbuf[y].replace(/ /g, nbsp);
if(scr_focused) {
if(y == cur_y)
// カーソル
scr += "<SPAN STYLE=\"background-color:white\"> </SPAN>";
}
scrary[y].innerHTML = scr;
scrmod[y] = false;
}
// リスタート
function restart(init) {
buffer = "";
if(init)
putstr("\r");
putstr("OK\r>");
i_current = -1;
list = input = false;
for_info = {i_var:-1};
for_stack.length = gosub_stack.length = 0;
brk = false;
}
// プログラム編集/ダイレクト コマンド
function edit_direct() {
text = buffer;
var num;
if(isNaN(num = get_num())) {
restart(true);
return;
}
if(num > 0) {
// プログラム編集
ignore_blanks();
var i;
var f = false;
for(i = 0; i < prog.length; i++) {
if(prog[i].num >= num) {
if(prog[i].num == num)
f = true;
break;
}
}
if(f) {
if(text.length)
// 置換
prog[i].text = text;
else
// 削除
prog.splice(i, 1);
}
else {
if(text.length)
// 挿入
prog.splice(i, 0, {num:num, text:text});
}
buffer = "";
putstr(">");
}
else {
exec(false);
}
}
// コマンド実行
function exec(cont) {
to_id = undefined;
for(var cnt = 10000; cnt; cnt--) {
var sts;
if(cont) {
sts = 1;
}
else {
var i;
if((i = get_token((i_current < 0) ? token1 : token2)) < 0) {
// アンマッチ
if(text.length)
// LET
sts = com_let();
else
sts = 2;
}
else {
sts = ((i_current < 0) ? func1 : func2)[i]();
}
}
switch(sts) {
case -1: // エラー または NEW
restart(true);
return;
case 0: // コマンド プロンプトに戻る
restart(false);
return;
case 1: // 次のコマンド
if(test_char(";"))
// 同じ行
break;
if(text.length) { // EOL でない
error_what();
restart(true);
return;
}
// fall thru
case 2: // 次の行
if(i_current < 0) { // ダイレクト モード
restart(false);
return;
}
if(++i_current == prog.length) { // プログラムの終わり
restart(false);
return;
}
// fall thru
case 3: // 新しい行
text = prog[i_current].text;
break;
case 4: // 続行
break;
case 5: // 実行中(LIST,INPUT)
return;
}
if(brk) {
restart(true);
return;
}
cont = false;
}
to_id = setTimeout(exec, 0, false);
}
//-------- コマンド --------------------
// LIST
function com_list() {
var num, lines;
if(isNaN(num = get_num()))
return -1;
if(test_char(",")) {
if(isNaN(lines = get_num()))
return -1;
if(lines < 0) // 数値でない
lines = 0;
}
else {
lines = Infinity;
}
if(check_eol())
return -1;
var i = 0;
if(num > 0) {
for(; i < prog.length; i++) {
if(prog[i].num >= num)
break;
}
}
list = true;
com_list2(i, lines);
return 5;
}
function com_list2(i, lines) {
if(!lines || i == prog.length || brk) {
restart(false);
return;
}
putstr(prog[i].num.toString().padStart(4, " ") + " " + prog[i].text + "\r");
setTimeout(com_list2, 0, i + 1, lines - 1);
}
// NEW
function com_new() {
if(check_eol())
return -1;
prog.length = 0; // クリア
elem_dl.download = "untitled.bas";
return -1;
}
// RUN
function com_run() {
if(check_eol())
return -1;
if(prog.length) {
i_current = 0;
return 3;
}
return 0;
}
// NEXT
function com_next() {
var i_var;
if((i_var = test_var()) < 0)
return -1;
if(i_var == 0x10000) { // 変数でない
error_what();
return -1;
}
for(; ; ) {
if(for_info.i_var < 0) {
error_what();
return -1;
}
if(for_info.i_var == i_var)
break;
for_info = for_stack.pop();
}
var val = tb_vars[for_info.i_var] + for_info.inc;
if(val >= -32768 && val <= 32767) {
tb_vars[for_info.i_var] = val;
if((for_info.inc < 0) ? (val >= for_info.lmt) : (val <= for_info.lmt)) { // 終値以内
({i_line:i_current, text:text} = for_info);
return 1;
}
}
for_info = for_stack.pop();
return 1;
}
// LET
function com_let() {
for(; ; ) {
if(assign_val() < 0)
return -1;
if(!test_char(","))
return 1;
}
}
// IF
function com_if() {
var val;
if(isNaN(val = expr()))
return -1;
if(val)
return 4;
return 2;
}
// GOTO
function com_goto() {
// 行番号
var num;
if(isNaN(num = expr()))
return -1;
if(check_eol())
return -1;
var i;
if((i = find_line(num)) < 0)
return -1;
i_current = i;
return 3;
}
// GOSUB
function com_gosub() {
// 行番号
var num;
if(isNaN(num = expr()))
return -1;
var i;
if((i = find_line(num)) < 0)
return -1;
gosub_stack.push({for_info:for_info, i_line:i_current, text:text}); // 現在の状態を保存する
for_info = {i_var:-1};
i_current = i;
return 3;
}
// RETURN
function com_return() {
if(check_eol())
return -1;
if(!gosub_stack.length) {
error_what();
return -1;
}
({for_info:for_info, i_line:i_current, text:text} = gosub_stack.pop());
return 1;
}
// REM
function com_rem() {
return 2;
}
// FOR
function com_for() {
for_stack.push(for_info); // 前の FOR 情報保存
for_info = {};
// 初期値
if((for_info.i_var = assign_val()) < 0)
return -1;
// 終値
if(get_token(["TO"]) < 0) {
// アンマッチ
error_what();
return -1;
}
if(isNaN(for_info.lmt = expr()))
return -1;
// 増分
if(get_token(["STEP"]) < 0) {
// アンマッチ
for_info.inc = 1;
}
else {
if(isNaN(for_info.inc = expr()))
return -1;
}
// 現在位置
for_info.i_line = i_current;
for_info.text = text;
// 同じ変数が使われている?
for(var i = for_stack.length - 1; i >= 0; i--) {
if(for_stack[i].i_var == for_info.i_var) { // 使われている
// 前の情報を破棄する
for_stack.splice(i, 1);
break;
}
}
return 1;
}
// INPUT
function com_input() {
if(com_input2())
return -1;
return 5;
}
function com_input2() {
input_text = text;
if(quoted_str()) {
if(!text.length) { // EOL
if(i_current < 0)
restart(false);
else
exec(true);
return 0;
}
if((input_i_var = test_var()) < 0)
return -1;
}
else {
if((input_i_var = test_var()) < 0)
return -1;
if(input_i_var == 0x10000) { // 変数でない
error_what();
return -1;
}
putstr(input_text.substr(0, input_text.length - text.length));
}
if(input_i_var != 0x10000) { // 変数
buffer = "";
putstr(":");
input = true;
return 0;
}
to_id = setTimeout(com_input3, 0);
return 0;
}
function com_input3() {
to_id = undefined;
if(input_i_var != 0x10000) {
var save_text = text;
text = buffer;
var f;
var val;
if(!(f = isNaN(val = expr()))) {
if(check_eol())
f = true;
}
input = false;
if(f) { // エラー
// 入力再実行
text = input_text;
com_input2();
return;
}
text = save_text;
tb_vars[input_i_var] = val;
}
if(test_char(",")) {
// さらに項目あり
if(com_input2() < 0)
restart(true);
return;
}
exec(true);
}
// PRINT
function com_print() {
ignore_blanks();
if(!text.length) { // EOL
putstr("\r");
return 1;
}
if(text.charAt(0) == ";") {
putstr("\r");
return 1;
}
var width = 8;
for(; ; ) {
if(test_char("#")) { // フォーマット
if(isNaN(width = expr()))
return -1;
if(width >= 64) {
error_how();
return -1;
}
}
else {
if(!quoted_str()) {
var val;
if(isNaN(val = expr()))
return -1;
putstr((val + 0).toString().padStart(width, " ")); // "+ 0": "-0" を回避する
}
}
if(test_char(",")) {
while(test_char(","))
putstr(" ");
if(!text.length) // EOL
return 1;
if(text.charAt(0) == ";")
return 1;
}
else {
putstr("\r");
return 1;
}
}
}
// STOP
function com_stop() {
if(check_eol())
return -1;
return 0;
}
//-------- 関数 ------------------------
// RND
function fnc_rnd() {
var n;
if(isNaN(n = paren()))
return NaN;
if(n < 0) {
error_how();
return NaN;
}
return Math.floor(Math.random() * n) + 1;
}
// ABS
function fnc_abs() {
var n;
if(isNaN(n = paren()))
return NaN;
if(n == -32768) {
error_how();
return NaN;
}
return Math.abs(n);
}
// SIZE
function fnc_size() {
return 32766;
}
//--------------------------------------
// トークンを取得する
// 戻り値 - トークン テーブルのインデックス(>=0),-1: アンマッチ
function get_token(token_tbl) {
ignore_blanks();
for(var i_token = 0; i_token < token_tbl.length; i_token++) {
var token = token_tbl[i_token];
var f = true;
for(var i = 0; i < token.length; i++) {
if(text.charAt(i) == ".") {
i++;
break;
}
if(text.charAt(i) != token.charAt(i)) {
f = false;
break;
}
}
if(f) { // マッチ
text = text.substr(i);
return i_token;
}
}
// アンマッチ
return -1;
}
// 変数に値を代入する
// 戻り値 - tb_vars のインデックス(>=0),-1: エラー
function assign_val() {
var i_var;
if((i_var = test_var()) < 0)
return -1;
if(i_var == 0x10000) { // 変数でない
error_what();
return -1;
}
if(!test_char("=")) {
error_what();
return -1;
}
var val;
if(isNaN(val = expr()))
return -1;
tb_vars[i_var] = val;
return i_var;
}
// 変数であるか調べる
// 戻り値 - tb_vars のインデックス(>=0),0x10000: 変数でない,-1: エラー
function test_var() {
ignore_blanks();
if(!text.length) // EOL
return 0x10000;
var c = text.charCodeAt();
if(c >= 64 && c <= 90) { // @,A 〜 Z
text = text.substr(1);
if(c == 64) { // 配列
var i;
if(isNaN(i = paren()))
return -1;
if(i < 0 || i > 16383) {
error_how();
return -1;
}
return i + 26;
}
return c - 65;
}
return 0x10000;
}
// 引用符で括られた文字列/制御コードを印字する
// 戻り値 - true: 引用符で括られた文字列/制御コードが見つかった,false: 見つからない
function quoted_str() {
var quot;
switch(test_char("\"'^")) {
case 1:
quot = "\"";
break;
case 2:
quot = "'";
break;
case 3: // ^
if(text.length) {
putstr(String.fromCharCode(text.charCodeAt() ^ 0x40));
text = text.substr(1);
}
// オリジナルの PATB は ^CR でも印字する
// それは使い道がないと思われる
return true;
default:
return false;
}
var str = text.split(quot, 1)[0];
putstr(str);
text = text.substr(str.length + 1);
return true;
}
// 式
// 戻り値 - 式の結果,NaN: エラー
function expr() {
var val1, val2;
if(isNaN(val1 = expr1()))
return NaN;
var op;
if((op = get_token([">=", "#", ">", "=", "<=", "<"])) < 0) // 比較演算子
// 比較演算子以外
return val1;
if(isNaN(val2 = expr1()))
return NaN;
switch(op) {
case 0: // >=
return (val1 >= val2) ? 1 : 0;
case 1: // #
return (val1 != val2) ? 1 : 0;
case 2: // >
return (val1 > val2) ? 1 : 0;
case 3: // =
return (val1 == val2) ? 1 : 0;
case 4: // <=
return (val1 <= val2) ? 1 : 0;
case 5: // <
return (val1 < val2) ? 1 : 0;
}
}
// 戻り値 - 式の結果,NaN: エラー
function expr1() {
var val1, val2;
if(test_char("-+") == 1) { // 負符号
if(isNaN(val1 = expr2()))
return NaN;
val1 = - val1;
}
else { // 正符号 または 符号なし
if(isNaN(val1 = expr2()))
return NaN;
}
for(; ; ) {
switch(test_char("+-")) {
case 1: // 加算
if(isNaN(val2 = expr2()))
return NaN;
val1 += val2;
break;
case 2: // 減算
if(isNaN(val2 = expr2()))
return NaN;
val1 -= val2;
break;
default:
return val1;
}
if(val1 > 32767 || val1 < -32768) {
error_how();
return NaN;
}
}
}
// 戻り値 - 式の結果,NaN: エラー
function expr2() {
var val1, val2;
if(isNaN(val1 = expr3()))
return NaN;
if(val1 == -32768) {
error_how();
return NaN;
}
for(; ; ) {
var op;
if(!(op = test_char("*/")))
return val1;
if(isNaN(val2 = expr3()))
return NaN;
if(val2 == -32768) {
error_how();
return NaN;
}
if(op == 1) { // 乗算
val1 *= val2;
if(val1 > 32767 || val1 < -32767) {
error_how();
return NaN;
}
}
else { // 除算
if(!val2) { // ゼロによる除算
error_how();
return NaN;
}
val1 = Math.trunc(val1 / val2);
}
}
}
// 戻り値 - 式の結果,NaN: エラー
function expr3() {
var i;
if((i = get_token(token3)) >= 0) // 関数
return func3[i]();
// 関数でない
var i_var;
if((i_var = test_var()) < 0)
return NaN;
if(i_var != 0x10000) { // 変数
if(tb_vars[i_var] == undefined)
return 0;
return tb_vars[i_var];
}
var val;
if(isNaN(val = get_num()))
return NaN;
if(val >= 0) // 数値
return val;
if(isNaN(val = paren()))
return NaN;
return val; // (式)
}
// 関数引数/配列インデックス/(式)
// 戻り値 - 式の結果,NaN: エラー
function paren() {
if(test_char("(")) {
var val;
if(isNaN(val = expr()))
return NaN;
if(test_char(")"))
return val;
}
error_what();
return NaN;
}
// 数値を取得する
// 戻り値 - 数値(>=0),-1: 数値でない,NaN: エラー
function get_num() {
ignore_blanks();
var w = text.match(/^(\d*)(.*)/);
if(w[1].length) { // 数値
text = w[2];
var val = parseInt(w[1], 10);
if(val > 32767) {
error_how();
return NaN;
}
return val;
}
return -1;
}
// 文字を調べる
// 引数 - 調べたい任意個の文字を連結した文字列,たとえば test_char("ABC")
// 戻り値 - 0: マッチしない,1: 1番目の文字にマッチ,2: 2番目の文字にマッチ,…
function test_char(char) {
ignore_blanks();
if(!text.length)
return 0;
var i = char.indexOf(text.charAt(0));
if(i < 0)
return 0;
text = text.substr(1);
return i + 1;
}
// 行の終わりか調べる
// 戻り値 - 0: OK(EOL),-1: EOL でない
function check_eol() {
ignore_blanks();
if(text.length) {
// EOL でない
error_what();
return -1;
}
return 0;
}
// 先頭の空白を無視する
function ignore_blanks() {
if(text.charAt(0) == " ")
text = text.replace(/^ */, "");
}
// 目的の行を探す
// 戻り値 - 行インデックス(>=0),-1: 見つからない
function find_line(num) {
for(var i = 0; i < prog.length; i++) {
if(prog[i].num >= num) {
if(prog[i].num == num)
return i;
break;
}
}
error_how();
return -1;
}
// エラー WHAT?
function error_what() {
put_error("WHAT?");
}
// エラー HOW?
function error_how() {
put_error("HOW?");
}
// エラー メッセージ
function put_error(msg) {
putstr("\r" + msg + "\r");
if(i_current >= 0 && !input) // ダイレクト モードと INPUT 以外
putstr(prog[i_current].num.toString().padStart(4, " ") + " "
+ prog[i_current].text.substr(0, prog[i_current].text.length - text.length)
+ "?" + text + "\r");
}
//----------------------------------------------------------
// ステートメント コマンド
token2 = ["NEXT", "LET", "IF", "GOTO", "GOSUB", "RETURN", "REM", "FOR", "INPUT", "PRINT", "STOP"];
func2 = [com_next, com_let, com_if, com_goto, com_gosub, com_return, com_rem, com_for, com_input, com_print, com_stop];
// ダイレクト コマンド
token1 = ["LIST", "NEW", "RUN", ...token2];
func1 = [com_list, com_new, com_run, ...func2];
// 関数
token3 = ["RND", "ABS", "SIZE"];
func3 = [fnc_rnd, fnc_abs, fnc_size];
nbsp = String.fromCharCode(160);
scrbuf = new Array(); // 画面バッファ
scrbuf.length = 25;
scrbuf.fill("");
scrmod = new Array(); // 画面バッファ更新フラグ
scrmod.length = 25;
scrmod.fill(false);
cur_x = cur_y = 0; // 画面 現在位置
scr_focused = false;
prog = []; // プログラム格納領域
var i_current; // 現在行インデックス(-1: ダイレクト モード)
var list, input; // LIST,INPUT 実行中フラグ
tb_vars = new Array(); // 変数 [0] 〜 [25]: A 〜 Z,[26] 〜: @ 配列
tb_vars.length = 26;
var text; // コマンド テキスト
var for_info; // FOR ループ情報
for_stack = []; // FOR ループ情報スタック
gosub_stack = []; // GOSUB 情報スタック
var input_text; // INPUT テキスト保存領域
var input_i_var; // INPUT 変数インデックス
var buffer; // 入力バッファ
var brk; // ブレーク フラグ
var to_id; // タイムアウト ID
var scrary = Array.from(document.getElementsByName("scr"));
elem_scr = document.getElementById("scr");
elem_load = document.getElementById("load");
elem_le = document.getElementById("le");
elem_save = document.getElementById("save");
elem_le.selectedIndex = 0;
elem_scr.onfocus = scr_focus;
elem_scr.onblur = scr_blur;
onkeydown = keydown;
onmouseup = mouseup;
elem_file = document.createElement("INPUT");
elem_file.type = "FILE";
elem_file.accept = ".bas";
elem_file.onchange = load_source2;
var file_reader;
elem_dl = document.createElement("A");
elem_dl.download = "untitled.bas";
elem_scr.focus();
restart(false);
//-->
</SCRIPT>
</BODY>
</HTML>
|