LANGUAGE
日本語 English

MOS言語仕様 > 構成要素

文字・記号
トークンと空白文字
コメント
識別子
キーワード
変数と変数宣言、データ型
配列変数
定数
演算子
構造体

文字・記号

MOSのプログラムの記述で使える文字は、アルファベット、数字、下に記す特殊記号です。
+  -  *  /  =  .  ,  ;  :  “  (  )  [  ]  {  }  !  %  &  \  <  >  _  ^  |  ~

戻る

トークンと空白文字

識別子、キーワード、定数、文字列定数、演算子、他の区切り子(カッコなど)のことを“トークン”と呼びます。これに対して、ブランク、タブ、改行、コメントを総称して“空白”といいます。空白はトークンを区切るために用いるときにだけ意味を持ち、そうでない場合はトランスレータは無視します。したがって、1つの空白を入れられる場所には任意の数の空白を入れられます。この性質を利用して、ソースプログラムの読み易さを高めることができます。

隣接した識別子、キーワード、定数を区別するために使用する空白は重要です。

戻る

コメント

"コメント" は、スラッシュとアスタリスク (/*) で始まる文字列です。コメントは、空白文字として扱われるか無視されます。コメントでは、"コメントの終了" を表すデリミタ (*/) 以外のすべての表示可能文字セット (改行文字を含む) を記述することができます。コメントを複数行にわたって書くこともできますが、ネストすることはできません。

コメントは空白文字を使うことができる場所であればどこにでも記述できます。トランスレータはコメントを1つの空白文字として扱うので、トークンの中にコメントを書くことはできません。トランスレータはコメント内の文字を無視します。

MOSのトランスレータは、2つのスラッシュ (//) で始まる1行のコメントをサポートしています。また、// から改行文字までをコメントとみなすので、複数行にわたるときは各行の頭に // を記述してください。

戻る

識別子

"識別子" または "シンボル" は、プログラムで使う変数、型、関数、ラベルに付ける名前です。識別子には、キーワードと同じスペル (大文字小文字も同じ) の名前を付けることはできませんが、キーワードを含む名前を用いることはできます。キーワードを識別子として使うことはできません。識別子は変数、関数の宣言の中で指定することによって作ります

識別子を宣言すると、それ以降のプログラム内で、識別子を使って値を参照できます。

識別子名の最初の文字は、アンダースコア、大文字または小文字のアルファベットでなければなりません。識別子に使用できる文字は次の通りで、31文字以内にしなければなりません。

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 _

戻る

キーワード

"キーワード" は、MOSトランスレータで特別な意味を持つ予約語です。MOS言語では次のキーワードを使います。

if else for while short long float double int void return switch case default break const char string goto continue struct MaxRobAxes CurrentPosition extern

戻る

変数と変数宣言、データ型

プログラムの中で使用するデータはメモリ内に格納する必要があります。そのために用いられるものが変数です。プログラムは変数を通してメモリにデータを格納したり,格納されたデータを参照したりします。
変数は「あるメモリ範囲に付けた名前」と考えることもできます。MOS言語では、変数は使用する前に定義する必要があります。

データ型には、char, short, long(int), float, double があり、それぞれの表現範囲は次の通りです。

データ型
範囲
char文字型(1バイト)-128~127
short整数型(2バイト)-32768~32767
long (int)整数型(4バイト)-2147483648~2147483647
float単精度実数型およそ10-38~1038 (有効桁7桁)
double倍精度実数型およそ10-308~10308 (有効桁15桁)

戻る

配列変数

配列変数は、変数の集合で、1次元、または2次元配列が使用できます。変数同様、グローバル配列変数、ローカル配列変数があり、使用する前に定義されている必要があります。

int a[10];
と宣言したとき確保される要素はa[0]~a[9]です。
関数の引数の配列変数は、値ではなく、参照が渡されます。

■1次元配列
書式)
データ型名 変数名[サイズ];

例)
char s[80]; // char型変数80個からなる配列s
double d[20]; // double型変数20個からなる配列d

■2次元配列
書式)
データ型名 変数名[サイズ1][サイズ2];

例)
short a[2][3]; // 二次元配列aの確保

■文字配列
文字列表現のためにはchar型配列を用います。2次元化も可能です。文字列の最後にNULL文字(’\0’)が付加されます。1次元配列では変数名だけで文字列全体を扱うことができます。2次元配列では変数名と1次元目だけでその配列の文字列全体を扱うことができます。
書式)
char 変数名[サイズ];
または
char 変数名[サイズ1] [サイズ2];

例)
char s[81]; // ASCII文字を80文字格納する配列s
char st[3][11]; // ASCII文字を10文字格納する2次元配列st
strcpy(s, “abcdefghijkimn”);
strcpy(st[0], “string”);
strcpy(st[1], “test”);
st[2] = “AB”; // これはNG
st[2][0]= ‘A’; // これはOK
st[2][1]= ‘B’; // これはOK
st[2][2]= 0;
Printf1(“s=\n%s”, s); // s= abcdefghijklmno
Printf2(“string=\n%s %s”, st[0], st[1]); // string=string test
Printf1(“st[2]=\n%s”, st[2]); // st[2]=AB

■ポジション配列
ポジション配列は、RobPtpMove、RobArcMove、RobGetCartePositionなどのMOSシステム関数で、動作目標位置、動作中継位置、現在位置を格納するためのdouble型配列です。2次元化も可能です。
書式)
double 変数名[MaxRobAxes];
または
double 変数名[サイズ] [MaxRobAxes];
MaxRobAxesは1つのロボットを構成する軸数です。定数8と同値です。

例えば、2軸ロボットであれば1軸目のポジションは配列要素[0]を、2軸目のポジションは配列要素[1]を設定、あるいは参照します。3軸目以上に相当する配列要素[2]以降は設定および参照は不要です。

ポジション配列は文字配列に似ています。1次元配列では変数名だけでロボット全軸のポジションを扱うことができます。2次元配列では変数名と1次元目だけでその配列のロボット全軸のポジションを扱うことができます。

例)
double GoalPos[MaxRobAxes]; // 目標位置を格納する一次元配列GoalPos
double PassPosA[2][MaxRobAxes]; // 中継位置を格納する二次元配列PassPosA
double CurrentPosA[3][MaxRobAxes]; // 現在位置を格納する二次元配列CurrentPosA
RobPtpMove(1, GoalPos, 1); // Robot1をGoalPosへ絶対位置移動
RobCircularMove(2, PassPosA[0], PassPosA[1], 1); // Robot2をPassPosA[0], PassPosA[1]を中継して真円補間で絶対位置移動
RobGetCartePosition(1, CurrentPosA[0] ); // Robot1の現在位置をCurrentPosA[0]に取得
Printf2(“\nX=%f, Y=%f”, CurrentPosA[0][0], CurrentPosA[0][1]); // CurrentPosA[0]を表示

戻る

定数

プログラム中では,変数への値の代入などで,定数を記述したい場合がよくあります。

■整定数
"整定数" は、整数値を表す10進数、16進数です。 “整定数”で負の数を表すときは、前にマイナス記号 (-) を付けます。 整定数の前に0xまたは0Xが付いているときは、その値が16進数であることを表します。前に何も付いていないときには、10進数になります。

■浮動小数点定数
"浮動小数点定数" は符号付き実数を表す10進数で、整数部、小数部、指数部からなります。
マイナス記号 (-) を前に付けないかぎり、浮動小数点定数は正数となります。浮動小数点定数は、float型、double型になります。

■配列定数初期化式
配列定数を初期化することができます。配列を初期化する場合、宣言時にサイズの指定を省略することができます。(多次元配列の場合では、1次元配列のみを省略できます。ただし省略する場合でも次元数分の [ ] は記述する必要があります。)
サイズを省略した場合は、初期化時に与えられた要素の数に合わせてメモリ領域が割り当てられます。
const double darray[][3] = { {1,2,3}, {4,5,6} };
定数式の右辺に算術式を記述することもできます。ただし、算術式内に配列定数を指定する事はできません。

例)
const int aaa[] = {1,2,3,4,5}; // OK
const int bbb = (6/2+2); // OK
const int ccc = (bbb*2/3); // OK
const int ddd = aaa[0]; // NG

■文字定数
文字定数は、該当する文字を一重引用符(‘)で囲むことで表現します。文字定数の値はその文字の持つ文字コード(ASCIIコード)になります。
c = ’A’;
とすると、変数cに文字’A’のASCIIコードである65が代入されます。
エスケープ文字は次の5種類をサポートします。

文字列コード略号機能
'¥n'0ALF復帰改行
'¥r'0DCR復帰
'¥t'09HT水平タブ
'¥"'22
"(文字列定数対策)
'¥¥'5C
¥自身

例)
switch(c1) {
case '1':
  if(c2 == 'A') {
    str[0] = 'B';
  }
  break;
}

戻る

演算子

■単項演算子

シンボル名前
-算術否定演算子
~補数演算子
!否定演算子
+単項プラス演算子

■二項演算子

シンボル名前
*乗算演算子
/除算演算子
%剰余演算子
+加算演算子
-減算演算子
<<左シフト演算子
>>右シフト演算子
<関係演算子(小さい)
>関係演算子(大きい)
<=関係演算子(小さいまたは等しい)
>=関係演算子(大きいまたは等しい)
==関係演算子(等しい)
!=関係演算子(等しくない)
&ビット演算子(ビットごとのAND)
|ビット演算子(ビットごとのOR)
^ビット演算子(ビットごとの排他的OR)
&&論理演算子(論理AND)
||論理演算子(論理OR)

■優先順位
演算子の優先順位と結合規則を下表にまとめます。優先順位の高いものから順に示しています。同じ行の演算子は同じ優先順位を持ち、結合規則に従って評価されます。

シンボル説明結合規則
[ ] ( )左から右
+ - ~ !単項右から左
* / %乗算、除算、剰余左から右
+加算、減算左から右
<< >>ビットごとのシフト左から右
< > <= >=関係左から右
== !=関係 (等値)左から右
&ビットごとのAND左から右
^ビットごとの排他的OR左から右
|ビットごとのOR左から右
&&論理AND左から右
||論理OR左から右
=単純代入右から左

戻る

構造体

構造体は幾つかの異なる型のデータをまとめて1つのデータ型として扱うものです。

■構造体のテンプレートの宣言
複数のデータ(メンバと呼びます)をまとめて1つの構造体の型枠を宣言します。この宣言は単に構造体の型を作ったにすぎず、領域の割当ては行われていません。
書式)
struct タグ名 {
  データ型 メンバ名;
};

例)
struct tagAAA {
  int idata;
  long ldata;
};

■構造体の宣言
テンプレートを使って実際にデータを宣言し、メモリ上に領域を確保します。構造体は「構造体変数」として1つの構造体を扱う事も出来ますし、複数の構造体をまとめて「構造体配列」として扱う事も出来ます。
書式)
タグ名 変数名の並び;
※"struct"は不要です。

例)
tagAAA aaa;
tagBBB bbb[20];

構造体定数はサポートしていません。
struct tagAAA {
  int idata;
  long ldata;
};
const tagAAA aaa = {1, 2}; // NG

構造体変数、構造体配列の { } を使用した初期化はサポートしていません。
struct tagAAA aaa = {1, 2}; // NG

■構造体の参照
構造体の各メンバは、「構造体変数名. メンバ名」のようにピリオド(.)を用いて指定します。この(.)を「ドット演算子」と呼びます。テンプレートを使って実際にデータを宣言し、メモリ上に領域を確保します。構造体は「構造体変数」として1つの構造体を扱う事も出来ますし、複数の構造体をまとめて「構造体配列」として扱う事も出来ます。

例)
tagAAA aaa;
aaa.idata = 123;

■構造体の一括代入
同一の型を持った構造体は一括して代入が可能です。

例)
tagAAA aaa;
tagAAA ccc;
ccc = aaa;

■構造体の入れ子
構造体を入れ子にして定義することが可能です。

例)
struct tagAAA {
  int idata;
  long ldata;
};
struct tagBBB {
  double ddata;
  long ldata;
};
struct tagIII {
  tagAAA sa;
  tagBBB sb;
};

ただし、次のようにまとめて記述することはできません。
struct tagIII {
  struct tagAAA {
    int idata;
    long ldata;
  } sa;
  struct tagBBB {
    double ddata;
    long ldata;
  } sb;
}; // NG

■構造体メンバの関数への引き渡し
構造体のメンバである配列変数(1次元、2次元)をシステム関数およびユーザ定義関数への引数として引き渡すことができます。

例1)
struct tagAAA {
  double speed;
  double goalpos[MaxRobAxes];
};
tagAAA aaa[10];
void setpos(double pos[MaxRobAxes]) {
  pos[0] = 10;
};
void main() {
  setpos(aaa[0].goalpos); // ユーザ定義関数へ構造体メンバを引き渡し
  RobPtpMove(1, aaa[0].goalpos, 1); // システム関数へ構造体メンバを引き渡し
}

例2)
struct tagAAA {
  double speed;
  double pos[2][MaxRobAxes];
};
tagAAA aaa[5];
void setpos(double pos[MaxRobAxes]) {
  pos[0] = 120;
  pos[1] = 150;
};
void printpos(double pos[MaxRobAxes]) {
  Printf2("\nx=%f, y=%f", pos[0], pos[1]);
}
void printpos (tagAAA st, char i) {
  Printf2("\nx2=%f, y2=%f", st.goalpos[i][0], st.goalpos[i][1]);
}
void getpos(double pos[MaxRobAxes]) {
  RobGetCartePosition(1, pos);
}
void main() {
  setpos(aaa[0].pos[0]); // ユーザ定義関数へ構造体メンバを引き渡し
  RobPtpMove(1, aaa[0].pos[0], 3); // システム関数へ構造体メンバを引き渡し
  getpos(aaa[1].pos[1]);
  printpos (aaa[1].pos[1]);
  printpos2(aaa[1], 1);
}

例3)
struct tagBBB {
  char hoge;
  char ponyo;
};
tagBBB hoo[5];
tagBBB hoohoo[1][1];
void pee(tagBBB val) {
  val.hoge = 10;
  val.ponyo = 20;
}
void main() {
  pee(hoo[0]);
  pee(hoohoo[0][0]);
}

戻る