Natural Tiny Basic (NT-Basic)は、C言語で記述された超小型のBasicインタプリタです。 Windows、Mac OS、Linux、組み込みシステムと、様々な実行環境で動作可能です。 マイコンを使った小規模組み込みシステムでも使用できるように設計されており、プラットフォームに依存しない複数の小規模なモジュールから構成されています。 内部設計は階層化されており拡張や改造も容易な事から、言語設計の学習素材としても活用できます。
REM命令を用いると、コメントを記述できます。
100 REM Complete example.
使用したい変数名は、あらかじめDIM命令で宣言してから使用します。
110 DIM X, Y, Z, I, J
120 X=2; Y=4; Z=8; I=0; J=0
PRINT命令を使うと変数の中身の値の表示が可能です。 変数Xの値を表示したい場合、以下のように記述します。 hal.cの実装によって標準出力やLCDなど出力先が決まります。 ダブル・クオーテーションを使って文字列の表示も可能です。 もし、改行をしたくない場合には、終わりに;記号を追加して下さい。 また、文字列に続けて変数の中身の値の表示も可能です。 カンマに続けて変数名を記述します。
130 PRINT X, Y, Z
140 PRINT "This is a text string."
150 PRINT "(X, Y, Z)="; X, Y, Z
GOTO命令を用いると、指定した行番号へ処理を移動します。
160 GOTO 180
170 PRINT "Control does not reach here."
180 PRINT "Our next control."
IF - THEN命令を用いると、条件判断を交えながら命令を実行できます。
190 IF X < 5 THEN PRINT "X < 5"
200 IF Y < 5 THEN PRINT "Y < 5"
210 IF Z < 5 THEN PRINT "Z < 5"
FOR- NEXT命令を用いると、繰り返し処理を実行できます。
220 FOR I = 1 TO 10
230 PRINT (X * I), (Y * I), (Z * I)
240 NEXT
250 FOR I = 1 TO 10
260 J = J + (X + Y + Z)
270 PRINT "J = J + (X + Y + Z) = "; J
280 NEXT
290 PRINT "J=";J
INPUT命令を用いると、hal.cで定義された標準入力から値を入力できます。
300 PRINT "Enter a number for I:";
310 INPUT I
320 INPUT "Enter a number for J: ", J
GOSUB - RETURN命令を用いると、サブルーチンの呼び出しとサブルーチンからの復帰を実行できます。
330 GOSUB 350
340 GOTO 370
350 PRINT "This is a sub routine."
360 RETURN
READは、抽象化されたハードウェアから何らかの読み込み処理を必要とする場合にhal.cに実装を追加する事で機能します。
変数Xで定義されたポート番号から値を読み込み、変数Yに格納します。 ポート番号0から値を読み込み、変数Zに格納します。
370 READ 0, X
380 PRINT "X=", X
390 READ I, J
400 PRINT "J=", J
WRITEは、抽象化されたハードウェアへ何らかの書き込み処理を必要とする場合にhal.cに実装を追加する事で機能します。
変数Xで定義されたポート番号へ、変数Yに格納されている値を書き込みます。 ポート番号0へ変数Zに格納されている値を書き込みます。
410 WRITE 0, X
420 WRITE I, J
END命令を使うとプログラムの終了を実行できます。
430 END
構文解説で断片的に用いたコードを繋ぎ合わせた完全なサンプル・コードを以下に示します。
100 REM Complete example.
110 DIM X, Y, Z, I, J
120 X=2; Y=4; Z=8; I=0; J=0
130 PRINT X, Y, Z
140 PRINT "This is a text string."
150 PRINT "(X, Y, Z)="; X, Y, Z
160 GOTO 180
170 PRINT "Control does not reach here."
180 PRINT "Our next control."
190 IF X < 5 THEN PRINT "X < 5"
200 IF Y < 5 THEN PRINT "Y < 5"
210 IF Z < 5 THEN PRINT "Z < 5"
220 FOR I = 1 TO 10
230 PRINT (X * I), (Y * I), (Z * I)
240 NEXT
250 FOR I = 1 TO 10
260 J = J + (X + Y + Z)
270 PRINT "J = J + (X + Y + Z) = "; J
280 NEXT
290 PRINT "J=";J
300 PRINT "Enter a number for I:";
310 INPUT I
320 INPUT "Enter a number for J: ", J
330 GOSUB 350
340 GOTO 370
350 PRINT "This is a sub routine."
360 RETURN
370 READ 0, X
380 PRINT "X=", X
390 READ I, J
400 PRINT "J=", J
410 WRITE 0, X
420 WRITE I, J
430 END
Natural Tiny Basic (NT-Basic) は、様々な環境で動作します。 以下に二つの異なる環境で動作させる場合の例について示します。
コンピュータ環境であればlibcを使ってプログラムを読み込むようなアプリケーションを簡単に構成できるでしょう。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ntbasic.h"
#include "progedit.h"
static int load_program(progedit_t *p, const char *filename)
{
char buf[BUFSIZ];
int line = 0;
FILE *fp = fopen(filename, "rb");
if (fp == NULL) {
return -1;
}
while (fgets(buf, sizeof(buf), fp) != NULL) {
line++;
if (progedit_insert(p, buf) != 0) {
printf("Insert failed.\nline=%d:%s\n", line, buf);
}
}
fclose(fp);
return line;
}
static int print_program(progedit_t *p)
{
char buf[BUFSIZ];
int line = 0;
while (progedit_fetch(p, line, buf, sizeof(buf)) == 0) {
line++;
printf(" %d: [%s]\n", line, buf);
}
return line;
}
int main(int argc, char *argv[])
{
ntbasic_t ntbasic;
ntbasic_error_t error;
progedit_t prog;
int line_files, line_progs;
char errmsg[BUFSIZ];
void *extobj = "This is a user external object for the test.";
/*
* Check the arguments.
*/
if (argc != 2) {
printf("usage: ntbasic \n");
return 1;
}
/*
* Load program from a file system.
*/
progedit_init(&prog);
line_files = load_program(&prog, argv[1]);
if (line_files < 0) {
printf("program read failed.\n");
return 2;
}
printf("[Program list]\n");
line_progs = print_program(&prog);
printf("\n");
printf("[Program information]\n");
printf(" %d lines readed.\n", line_files);
printf(" %d lines stored.\n", line_progs);
printf(" %d bytes.\n", (int)strlen(PROGEDIT_PROGRAM(&prog)));
printf("\n");
/*
* Setup and execute.
*/
error = ntbasic_setup(&ntbasic, PROGEDIT_PROGRAM(&prog), extobj);
while (error == NoError) {
error = ntbasic_execute(&ntbasic);
}
/*
* Check the termination code.
*/
if (error != EndOfTheProgram) {
ntbasic_get_error_message(&ntbasic, error, errmsg, sizeof(errmsg));
printf("Error: %s\n", errmsg);
}
return (error == EndOfTheProgram) ? 0 : error;
}
#include "ntbasic.h"
int main(void)
{
ntbasic_t ntbasic;
ntbasic_error_t error;
char *program =
"100 PRINT \"This is a test\"\n" \
"110 END\n";
void *extobj = (void *)0;
error = ntbasic_setup(&ntbasic, program, extobj);
while (error == NoError) {
error = ntbasic_execute(&ntbasic);
}
while (1) {
}
}
Natural Tiny Basic (NT-Basic) は、システムの中で少なくとも3つの層で全体が構成される想定で作られています。
Natural Tiny Basic (NT-Basic) は、小規模組み込みシステムで動作させる事を前提に設計されています。 また、libcを含む外部ライブラリへの依存は一切なく、最小限の依存関係で成立するように意図されています。 シェル上でソースコードに対して「grep 'include <' *」を実行して頂ければわかりますが、外部ライブラリを参照するinclude文は、main.cとhal.cにしか含まれません。 そして、これらmain.cとhal.cは、単にコンピュータ環境上で動作を確認するために仮に実装されたもので、Natural Tiny Basic (NT-Basic)の本質的なものではありません。 main.cは、一般的なファイルシステムからプログラムを読み込む例として示したもので、小規模組み込みシステムでは別の形を取るかもしれません。 hal.cは、ハードウェア抽象化層です。対象システムに応じて実装を変更可能です。 progeditとtexteditは、サンプルにおけるプログラム格納領域を提供する機能を持ちますが、実際の組み込みでは不要でしょう。
アプリケーション層は、組み込み対象システムに完全に依存する層です。 Natural Tiny Basic (NT-Basic)のデフォルトの実装は、コンピュータ環境で実行する事を前提にlibcを用いたファイル読み込み型のアプリケーションになっています。 組み込み形態に応じてデフォルトの実装を取り除いて所望のアプリケーションを構成して下さい。
モジュール名 | 機能 |
---|---|
main | コンピュータ環境で実行可能なサンプル・プログラム |
progedit | プログラム・エディタ・モジュール |
textedit | テキスト・エディタ・モジュール |
NT-Basic層は、Natural Tiny Basic (NT-Basic)を構成する主要なモジュールが含まれる層です。
NT-Basicの上位層は、アプリケーション層との界面を司る部分で、全てのインタフェースの源を提供します。 幾つかのモジュールで構成されていますが、基本的にntbasic.hをインクルードするだけで済むようになっています。
モジュール名 | 機能 |
---|---|
ntbasic | NT-Basicのインターフェースモジュール |
NT-Basicの中位層は、NT-Basicが内部で使用するモジュール群で構成されています。 一部の定義はアプリケーション層でも使用しますが、必要な依存関係はntbasic.hから呼び出されて自動的に解決されます。
モジュール名 | 機能 |
---|---|
core | NT-Basicのコア・モジュール |
statement | NT-Basicの文法評価処理モジュール |
expression | NT-Basicの数式評価処理モジュール |
variable | NT-Basicの変数管理処理モジュール |
NT-Basicの下位層は、NT-Basicがモジュール内部で使用するライブラリが含まれる層です。 組み込みで特に重要なのはhal.cで、この実装によってPRINT構文やINPUT構文がどこから入力を得るのかが決まります。
モジュール名 | 機能 |
---|---|
tinyrand | 乱数発生モジュール |
ntlibc | 独自libcモジュール |
hal | ハードウェア層抽象化モジュール |
Natural Tiny Basic (NT-Basic)の組み込みに際して、上記のアプリケーション層、NT-Basic層が階層毎に適切に分離されている設計において、特にハードウェア層に求められる事はありません。 ハードウェアとの界面はNT-Basicの下位層に含まれるhal.cによって分離定義されます。
hal.cの実装から始めて下さい。
組み込みシステムの場合には、progeditモジュール、texteditモジュールは不要かもしれません。
はい。
小規模なモジュールに分割設計されたNatural Tiny Basic (NT-Basic)では、既存の命令を参考にして独自の命令を簡単に追加できます。
追加したい独自の命令に一番近い既存構文を参考に命令を追加して下さい。
命令の基本定義はcore.hに存在し、statement.cで実際の構文制御を行ないます。
ntbasic.cに追加した命令に至る処理を追加して下さい。
はい。
READ命令、WRITE命令を使って可能です。
制御の詳細はhal.cに隠蔽されており、この実装詳細を変更して下さい。
100 PRINT "This program demonstrates HAL I/O."
110 DIM I, O, V
120 INPUT "INPUT PORT=", I
130 INPUT "OUTPUT PORT=", O
140 READ I, V
150 PRINT "Input"
160 PRINT "Port"; I; "Value"; V
170 WRITE O, V
180 PRINT "Output"
190 PRINT "Port"; O; "Value"; V
200 END
変数は対象処理系におけるintで処理されます。
変数名は最大8文字で32個まで定義できます。
扱いたい変数の個数を増やしたり、許容する変数名の最大文字数を増やしたい場合には、variable.hにある定義を変更して下さい。
はい。
以下のサンプルもご覧下さい。
100 PRINT "This program demostrates nested FOR loops."
110 FOR X = 1 TO 5
120 FOR Y = 1 TO 10
130 PRINT X; Y; X*Y
140 NEXT
150 NEXT
100 PRINT "This program demonstrates nested GOSUBs."
110 INPUT "enter a number: ", I
120 GOSUB 140
130 END
140 FOR T = 1 TO I
150 X = X + I
160 GOSUB 190
170 NEXT
180 RETURN
190 PRINT X;
200 RETURN
リリース日 | バージョン | リンク | リリースノート |
---|---|---|---|
2014/11/30 | Version 0.3.0 | Version 0.3.0 |
|
2012/11/04 | Version 0.2.0 | Version 0.2.0 |
|
2012/09/23 | Version 0.1.1 | Version 0.1.1 |
|
2012/09/22 | Version 0.1.0 | Version 0.1.0 |
|
2012/09/08 | Version 0.0.1 | Version 0.0.1 |
|
/**
* ===============================================================
* Natural Tiny Basic (NT-Basic) - A tiny BASIC interpreter
* ===============================================================
* Copyright (c) 2012-2014 Shinichiro Nakamura
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
* ===============================================================
*/