(1)データ:実数(double)、複素数、行列(実数、複素数)が扱えること。 (2)制御命令(for文、if文、while文など)があること。 (3)ユーザが定義できる関数がある。 (4)コマンドラインからだけでなく、ファイルに書かれたプログラムも読める。 (5)オブジェクトが定義でき、演算子多重定義ができる。 (6)絵が書ける。
#include <stdlib.h>
#include "u.math.h"
#include "MEM.h"
#include "DBG.h"
#include "calc.h"
#include "bignum.c"
main () {
/*行列演算の変数宣言*/
static rec_mat x,y,z;
static c_recmat a,b,c;
int row,col,colm1,row1,colm2,row2,i,s,fg;
scaler mdeterm,determ();
string *str;
complex ccef,c_math();
/*複素数演算の変数宣言*/
complex c_assign(),c_math(),c_exp((), c_pow(),
c_log10(), c_sin(), c_log(), c_cos(),
c_tan(),
double x, y, z; /*指定通りのdouble型*/
scaler c_mag(), c_arg(), cls();
/*行列の固有値問題の変数宣言*/
int n;
static rec_mat a, x;
/*実行列、複素行列main*/
void
mat_product(),mat_get(),mat_print();
while(1) {
cls();
printf("Input of a Real Matrix \n");
printf("Input of a Complex Matrix \n");
printf("a product of Real Matrix \n");
prinft("a product of Complex Matrix \n");
printf("an add of Real Matrix \n");
printf("an add of Complex Matrix \n");
scanf("%d,&s");
if(s>=99) exit();
switch(s) {
case1: cls();
mat_get(x,&row1,&colm1,"matrix A input ");
cls();
mat_get(y,&row2,&colm2,"matrix B input ");
row=row1;
col=colm1; fg=3;
break;
case2: mat_product(x,y,row1,colm1,colm2,z);
col=colm2;
str="mat_product";
fg=0;
break;
case3: mat_product(x, y, row1, colm1, colm2, z);
col=colm2; str="mat_product";fg=0;
break;
case4: c_mat_product(a, b, row1,colm1, colm2, c);
row=row1; col=colm1; str="c_mat_product"; fg=1;
case5: mat_add(x, y, row1, colm1, z);
str="mat_add"; fg=0;
break;
case6: c_mat_add(a, b, row1, colm1, c);
str="mat_add"; fg=1;
}
switch(fg) {
case 0: cls();
mat_print(x,row1.colm1,"Input matrix X");
mat_print(y,row2,colm2,"Input matrix Y");
mat_print(z,row,col,str)
break;
case 1: cls();
mat_print(x,row,col,"matrix X");
printf("determinant = %lf\n" , mdeterm);
break;
}
}
/*複素演算main*/
x=c_assign(1.0, 2.0);
y=c_assign(2.0, 4.0);
c_print("c_x= ",x);
c_print("c_y= ",y);
c_print("c_plus=", c_math(x,plus,y));
c_print("c_minus=", c_math(x,minus,y));
c_print("c_multiply=", c_math(x,multiply,y));
c_print("c_devide=",c_math(x,divide,y));
c_print("c_exp=",c_exp(x));
c_print("c.mag and arg=",c_assign(c_mag(x),c_arg(x)));
printf("type any key:"); ci(); cls();
x=c_assign(.5,.1);
c_print("c_x=",x);
c_print("c_inv=",c_inv(x));
c_print("c_pow=",c_pow(x,2.0));
c_print("c_sin=",c_sin(x));
c_print("c_cos=",c_cos(x));
c_print("c_tan=",c_tan(x));
c_print("c_log10=",c_log10(x));
c_print("c_log=",c_log(x));
printf("type any key:"); ci();
/*固有値問題演算main*/
while(1) {
switch(menu()) {
case 1:mat_get(a,&n);break;
case 2:mat_print(a,n);break;
case 3:xqr(a,x,n);print_eig_vec(a,x,n);break;
case 4:exit(0);
}
/*bisonでの四則演算main*/
#if CONSOLEAP
#define ANSFORM "\nanswer is %f\n"
#define ANSFORMX "\nanswer is %X\n"
char Buf[ 128 ];
gets( Buf );
lexpos = Buf;
yyparse();
puts( OutBuf );
}
/***************-<<実数行列、複素数行列演算>>-****************/
void mat_print(ma,row,col,matname)rec_mat ma;int row,col;
string *matname; {
int i, j, ii;
printf("実行列 &s\n" ,matname);
for (i=1; i <= col; i++) {
for (j=0; j <= col; j++)
printf("%7.2lf", ma[i][j]);
printf("\n");
}
printf("-------- end %s --------\n",matname);
}
void mat_print(mat, m, n, matname)c_recmat mat; int m,n;
string *matname; {
int i, j, ii;
printf("複素行列 %s\n", matname);
for (i=1; i<=m; i++) {
for (j=1; j<=n; j++)
printf("[%7.2lf %7.2lf] ",
mat[i][j].re,mat[i][j].im);
printf("\n");
}
printf("------end %s --------\n" ,matname);
/*実行列の入力*/
void mat_get(a,m,n,matname)rec_mat a;int *m,*n;string *matname;{
int i, j;
printf("----------%s --------\n",matname);
printf("行数を入力(<%d)",MAXR);scanf("%d",m);
printf("列数を入力(<%d)",MAXC);scanf("%d",n);
for (i=1; i < *m+1; i++)
for (j=1; j<*n+1; j++) {
printf("MATRIX[%2d][%2d]= ",i,j);
scanf("%lf",&a[i][j]);
}
}
/*複素行列の入力*/
void c_mat_get(mat, m, n, matname)c_recmat mat;int *m, *n;
string *matname; {
int i, j;
printf("----%s----\n",matname);
printf("行数を入力(<%d)",MAXR); scanf("%d", m);
printf("列数を入力(<%d)",MAXC); scanf("%d" ,n);
for(i=1; i<=l; i++)
for(j=1; j<=n; j++) {
t=0.0;
for(k=1; k<=m; k++)
t+=ma[i][k]*mb{k][j];
mz[i][j]=t;
}
}
/*実行列の積の演算*/
void mat_product(ma,mb,l,m,n,mz)rec_mat ma,mb,mz;int l,m,n; {
int i, j, k; scaler t;
printf("product of matrix A[%d][%d] and B[%d][%d]",l,m,m,n);
for (i=1; i<=l; i++)
for (j=1; j<=n; j++){
t=0.0;
for (k=1; k <= m; k++)
t+=ma[i][k]*mb[k][j];
mz[i][j]=t;
}
}
/*複素行列の積の演算*/
void c_mat_product(maata, matb, l, m, n, matz) c_recmat mata, matb, maatz;
int l, m, n; {
int i, j, k; complex t;
for (i=1; i<=l+1; i++)
for(j=1; j<n+1; j++) {
t.re=t.im=0.0;
for(k=1; k<m+1; k++)
t=c_math(t,plus, c_math(mata[i][k], multiply matb[k][j]));
matz[i][j]=t;
}
}
/*実行列の和の演算*/
void mat_add(ma, mb, nrow, ncol, mz)rec_mat ma, mb, mz; int nrow, ncol; {
int i, j;
for(i=1; i<=ncol; i++)
for(j=1; j<=ncol+1; j++)
matz[i][j]=c_math(mata[i][j], plus, matb[i][j]);
}
/*複素行列の和の演算*/
void c_mat_add(mata, matb, nrow, ncol, matz)
c_recmat mata, matbm matz; int nroq, ncol; {
int i, j;
for(i=1; i<=nrow; i++)
for(j=1; j<ncol+1; j++) {
matz[j][i].re=mata[i][j].re;
matz[j][i].im=mata[i][j].im;
}
}
/***************-<<複素数演算>>-*******************/
c_print(prompt,x)char *prompt; complex x;{
printf("%s\t(%lf,%lf)\n", prompt,x.re, x.im);
}
/*スカラー入力*/
complex c_assign(x,y)scaler x, y;{
complex p;
p.re=x; p.im=y;
return(p);
}
/*複素数の四則演算のswitch文による切り替え*/
complex c_math(c1,op,c2)complex c1, c2; opt op;{
scaler p;
complex t;
switch(op) {
case plus: t.re=c1.re+c2.re;
t.im=c1.im+c2.im;
break;
case minus: t.re=c1.re-c2.re;
t.im=c1.im-c2.im;
break;
case multiply: t.re=c1.re*c2.re - c1.im*c2.im;
t.im=c1.re*c2.im + c1.im*c2.re;
break;
case divide: p=sqr(c2.re)+sqr(c2.im);
t.re=(c1.re*c2.re + c1.im*c2.im) / p;
t.im=(c1.im*c2.re - c1.re*c2.im) / p;
break;
default: t.re=c1.re;
t.im=c1.im;
break;
}
return(t);
}
/***以下三角関数等の関数定義***/
complex congugate(x)complex x;{
complex t;
t.re=x.re;
t.im=-x.im;
return(t);
}
scaler c_mag(x)complex x;{
complex t, c_math();
t=c_math(x,multiply,conjugate(x));
return(sqrt(t.re));
}
scaler c_arg(x)complex x;{return(atan2(x.re, x.im));}
/*指数定義*/
complex c_exp(x)complex x;{
complex t;
t.re=exp(x.re)*cos(x.im);
t.im=exp(x.re)*sin(x.im);
return(t);
}
complex c_pow(x,y)complex x;scaler y;{
scaler z_abs, z_arg;
complex ca, cb;
z_abs=pow(c_mag(x),y);
a_arg=y*c_arg(x);
ca=c_assign(z_abs, o.o);
cb=c_exp(0.0,z_arg);
retrun(c_math(ca,multiply,cb));
}
/*対数定義*/
complex c_log(x)complex x; {
scaler tmp;
complex ctmp;
tmp=log((x.re*x.re+x.im*x.im)/2.0);
ctmp=c_assign(tmp,c_arg(x));
}
complex c_log10(x)complex x;{
scaler t,tt;
t=c_assign(log10(EX), 0.0);
tt=c_math(t,multiply,c_log(x));
return(tt);
}
/*sin関数定義*/
complex c_sin(x)complex x;{
scaler yp,ym;
complex t;
yp=exp(x.im); ym=1.0/yp;
t=c_assign(sin(x.re)*(yp+ym)/2.0,
cos(x.re)*(yp-ym)/2.0;
return(t);
}
/*cos関数定義*/
complex c_cos(x)complex x;{
scaler yp, ym;
complex t;
yp=exp(x.im);ym=1.0/yp;
t=c_assign(cos(x.re)*(yp+ym)/2.0,
sin(x.re)*(yp-ym)/2.0;
return(t);
}
/*tan関数定義*/
complex c_tan(x){retrun(c_math(c_sin(x),divide,c_cos(x)));}
/***********-<<QR法による行列の固有値問題>>-*************/
int menu() {
int s;
cls();
printf("固有値と固有ベクトル\n");
do {
printf("Choose 1〜4.\n");
scanf("%d", &s);
}
while((s<1)||(s>3)&&(s!4));
return s;
}
mat_print(a,n) rec_mat a; int n; {
int i, j;
for(i=0; i<=n; i++) {
for(j=1; j<=n; j++)
printf("%7.4lf", a[i][j]);
printf("\n");
}
printf("Type any key:"); ci();
}
/*求める固有値行列の行数、列数の入力*/
mat_get(a,m,n,matname) rec_mat a; int *m, *n; string *matname; {
int i,j;
printf("行数は?");scanf("%d",m);
printf("列数は?");scanf("%d",n);
for(i=1; i<+m+1; i++)
for(j=1; j<*n+1; j++) {
printf("Please input a[%2d][%2d]=",i,j);
scanf("%lf", &a[i][j]);
}
}
put_vec(e,n) s_vector e; int n; {
int i;
for(i=1; i<=n; i++)
printf("eigen[%2d]=%e\n", i, e[i]);
}
print_eig_vec(a,b,n)rec_mat a, b; int n; {
int i, j;
for(i=1; i<=n; i++)
printf("%lf", a[i][i]);
printf("\n\n Eigen Vector \n");
for(i=1; i<=n; i++) {
for(j=1; j<=n; j++)
printf("%lf ", b[i][j]);
printf("\n");
}
ci();
}
/*固有値の解法*/
gvens(a,r,n) rec_mat a,r; int n; {
int i, j, k, p, q;
scaler sinx, cosx, tanx,rip, aip, api, app, aqq;
unit(r,n);
for(p=2; p<n; p++)
for(q=p+1; q<=n; q++) {
sinx=tanx*cosx;
cosx=1.0/sqrt(1.0+sqr(tanx));
tanx=-a[q][p-1]/a[p][p-1];
for(i=1; i<=n; i++) {
rip=r[i][p]*cosx-r[i][q]*sinx;
r[i][q]=r[i][p]*sinx-r[i][q]*cosx;
r[i][p]=rip;
if((i!=p)&&(i!q)) {
aip=a[i][p]*cosx-a[i][q]*sinx;
a[i][q]=a[i][p]*sinx+a[i][q]*cosx;
}
}
for(i=1; i<=n; i++)
if((i!=p)&&(i!=q)) {
api=a[p][i]*cosx-a[q][i]*sinx;
a[q][i]=a[p][i]*sinx+a[q][i]*cosx;
}
app=a[p][p]*sqr(cosx)-2.0*a[p][q]*sinx*cosx+a[q][q]*sqr(sinx);
aqq=a[p][p]*sqr(sinx)*2.0*a[p][q]*sinx*cosx+a[q][q]*sqr(cosx);
a[p][q]=a[p][q]*(sqr(cosx)-sqr(sinx))+(a[p][p]-a[q][q])*sinx*cosx;
a[q][p]=a[q][p]*(sqr(cosx)-sqr(sinx))+(a[p][p]-a[q][q])*sinx*cosx;
a[p][p]=app;
a[q][q]=aqq;
a[q][p-1]=0.0;
}
}
unit(a,n) rec_mat a; int n; {
int i, j;
for(i=1; i<=n; i++) {
a[i][i]=1.0;
for(j=i+1; j<=n; j++) a[i][j]=a[j][i]=0.0;
}
}
/*固有ベクトルの解法*/
qr(a,r,n) rec_mat a, r; int n; {
int i, j, k, m, cnt;
scaler d1, d2, rmdal, rmda2, rmdak, sinx, cosx, tanx, aij,qji, pji, tmp,
eps;
static rec_mat q, p, z;
eps=1.0E-20;
unit(q,n);
for(m=n; m>=2; m--)
cnt=0;
do {
d1=a[m][n]+a[m-1][m-1];
d2=sqr(d1)-4.0*(a[m-1][m-1]*a[m][m]-a[m][m-1]*a[m][m-1]*a[m-1][m]);
d2=sqrt(d2);
rmda1=(d1+d2)/2.0;
rmda2=(d1-d2)/2.0;
rmdak=(fabs(rmda1-a[m][m])<fabs(rmda2-a[m][m]))?rmdal:rmda2;
unit(p,n);
for(i=1; i<=m; i++)a[i][i]-=rmdak;
for(i=1; i<m; i++) {
sinx=cosx*tanx;
cosx=1.0/sqrt(1.0+sqr(tanx));
tanx=a[i+1][i].a[i][i];
for(j=1; j<=n; j++) {
aij=a[i][j]*cosx+a[j+1][j]*sinx;
a[i+1][j]-=a[i][j]*sinx+q[j][i+1]*cosx;
q[j][i]=qji;
pji=p[j][i]*cosx+p[j][i+1]*sinx;
p[j][i+1]-=p[j][i]*sinx+p[j][i+1]*cosx;
p[j][i]=pji;
}
}
for(i=1; i<=n; i++)
for(j=1; g<=n; j++) z[i][j]=a[i][j];
for(i=1; i<=n; i++)
for(j=1; j<=n; j++) {
tmp=0.0;
for(k=1; k<=n; k++)tmp+=z[i][k]*p[k][j]; a[i][j]=tmp;
}
for(i=1; i<=m; i++) a[i][i]+=rmdak;
cnt++;
}
while(fabs(a[m][m-1])>eps);
}
for(i=1; i<=n; i++)
for(j=1; j<=n; j++) {
for(k=1; k<=n; k++)tmp+=r[i][k]*q[k][j];
z[i][j]=tmp;
}
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)r[i][j]=z[i][j];
}
xqr(a,x,n)rec_mat a, x; int n;{
gvens(a,x,n);
qe(a,x,n);
}
/****************-<<bisonによる四則演算>>-******************/
#define YYSTYPE double
#define CONSOLEAP 0 /* if console AP then set not zero */
#ifdef DEBUG
#define DebOut( s ) printf( "<%s>", s )
#else
#define DebOut( s )
#endif
char OutBuf[ 64 ]; /* result output buffer */
YYSTYPE result;
%}
%token EOL
%token NUMBER
%token LP RP
%left ADDOP SUBOP
%left MULOP DIVOP
%right MINUS
%start s
%%
s : expr EOL
{
result = $1;
dspresult();
YYACCEPT;
}
;
expr : expr ADDOP expr
{ $$ = $1 + $3; }
| expr SUBOP expr
{ $$ = $1 - $3; }
| expr MULOP expr
{ $$ = $1 * $3; }
| expr DIVOP expr
{
if( $3 == 0.0 ) {
sprintf( OutBuf, "divieded by zero");
YYACCEPT;
} else {
$$ = $1 / $3;
}
}
| SUBOP expr %prec MINUS
{ $$ = -$2; }
| LP expr RP
{ $$ = $2; }
| NUMBER
{ $$ = $1; }
;
%%
/*yylex の現在の位置*/
static const char* lexpos = NULL;
#if CONSOLEAP
#define ANSFORM "\nanswer is %f\n"
#define ANSFORMX "\nanswer is %X\n"
char Buf[ 128 ];
/* コンソールアプリケーションの場合のメインルーチン */
#else
#define ANSFORM "%18.16g"
#define ANSFORMX "%X"
char *calculate( const char *buf )
{
lexpos = buf;
yyparse();
return( OutBuf );
}
#endif
void dspresult( void )
{
if( DspMode == 0 ) { /* if decimal */
sprintf( OutBuf, ANSFORM, result );
} else {
sprintf( OutBuf, ANSFORMX, (int)result );
}
}
int isnum( char c )
{
return( c >= '0' && c <= '9' ? 1 : 0 );
}
char toupperalph( char c )
{
return( c >= 'a' && c <= 'z' ? c - ( 'a' - 'A' ) : c );
}
int ishex( char c )
{
return( isnum( c ) || ( c >= 'A' && c <= 'F' ) );
}
int hex( char c )
{
return( c <= '9' ? c - '0' : c - 'A' + 10 );
}
/***字句解析***/
static int yylex()
{
char c;
c = *lexpos;
while( c == ' ' ) { /* 空白読み飛ばし */
c = *++lexpos;
}
lexpos++;
switch( c ) {
case '\0':
DebOut( "EOL" );
return( EOL );
break;
case '+':
DebOut( "ADDOP" );
return( ADDOP );
break;
case '-':
DebOut( "SUBOP" );
return( SUBOP );
break;
case '*':
DebOut( "MULOP" );
return( MULOP );
break;
case '/':
DebOut( "DIVOP" );
return( DIVOP );
break;
case '(':
DebOut( "LP" );
return( LP );
break;
case ')':
DebOut( "RP" );
return( RP );
break;
default:
if( isnum( c ) || c == '.' ) {
lexpos--;
if( c == '0' && *(lexpos + 1) != '.' ) { /* if hex */
yylval = 0;
while( ishex( c = toupperalph( *++lexpos ) ) ) {
yylval = yylval * 16 + hex( c );
}
} else {
int state;
double point = 0.1;
if( c == '.' ) {
state = 1;
yylval = 0.0;
} else {
state = 2;
yylval = c - '0';
}
while( state ) {
c = *++lexpos;
switch( state ) {
case 2:
if( isnum( c ) ) {
yylval = 10.0 * yylval + ( c - '0' );
}
else if( c == '.' ) {
state--;
} else {
state = 0;
}
break;
case 1:
if( isnum( c ) ) {
yylval += point * ( c - '0' );
point /= 10.0;
} else {
state = 0;
}
break;
}
}
}
#ifdef DEBUG
printf( "<NUMBER:%f>", yylval );
#endif
return( NUMBER );
} else {
return( c );
}
break;
}
}
int yyerror( char *msg )
{
sprintf( OutBuf,"%s", msg );
return( 0 );
}
/**************-<<制御文の制定>>-***************/
/*calc.y*/
#define YYDEBUG 1
%}
%union {
char *identifier;
ParameterList *parameter_list;
Expression *expression;
}
%token <expression> INT_LITERAL
%token <expression> DOUBLE_LITERAL
%token <identifier> IDENTIFIER
%token DEFINE IF ELSE WHILE LP RP LC RC SEMICOLON COMMA ASSIGN
EQ NE GT GE LT LE ADD SUB MUL DIV MOD
%type <parameter_list> parameter_list
%type <expression> expression expression_list
equality_expression relational_expression
additive_expression multiplicative_expression
unary_expression postfix_expression primary_expression
if_expression while_expression
%%
translation_unit
: definition_or_expression
| translation_unit definition_or_expression
;
definition_or_expression
: function_definition
| expression SEMICOLON
{
clc_eval_expression($1);
}
| error
{
yyclearin;
clc_reopen_current_storage();
}
;
function_definition
: DEFINE IDENTIFIER LP parameter_list RP LC expression_list RC
{
clc_function_define($2, $4, $7);
}
| DEFINE IDENTIFIER LP RP LC expression_list RC
{
clc_function_define($2, NULL, $6);
}
;
parameter_list
: IDENTIFIER
{
$$ = clc_create_parameter($1);
}
| parameter_list COMMA IDENTIFIER
{
$$ = clc_chain_parameter($1, $3);
}
;
expression_list
: expression
{
$$ = clc_create_expression_list($1);
}
| expression_list COMMA expression
{
$$ = clc_chain_expression_list($1, $3);
}
;
expression
: equality_expression
| IDENTIFIER ASSIGN equality_expression
{
$$ = clc_create_assign_expression($1, $3);
}
;
equality_expression
: relational_expression
| equality_expression EQ relational_expression
{
$$ = clc_create_binary_expression(EQ_EXPRESSION, $1, $3);
}
| equality_expression NE relational_expression
{
$$ = clc_create_binary_expression(NE_EXPRESSION, $1, $3);
}
;
relational_expression
: additive_expression
| relational_expression GT additive_expression
{
$$ = clc_create_binary_expression(GT_EXPRESSION, $1, $3);
}
| relational_expression GE additive_expression
{
$$ = clc_create_binary_expression(GE_EXPRESSION, $1, $3);
}
| relational_expression LT additive_expression
{
$$ = clc_create_binary_expression(LT_EXPRESSION, $1, $3);
}
| relational_expression LE additive_expression
{
$$ = clc_create_binary_expression(LE_EXPRESSION, $1, $3);
}
;
additive_expression
: multiplicative_expression
| additive_expression ADD multiplicative_expression
{
$$ = clc_create_binary_expression(ADD_EXPRESSION, $1, $3);
}
| additive_expression SUB multiplicative_expression
{
$$ = clc_create_binary_expression(SUB_EXPRESSION, $1, $3);
}
;
multiplicative_expression
: unary_expression
| multiplicative_expression MUL unary_expression
{
$$ = clc_create_binary_expression(MUL_EXPRESSION, $1, $3);
}
| multiplicative_expression DIV unary_expression
{
$$ = clc_create_binary_expression(DIV_EXPRESSION, $1, $3);
}
| multiplicative_expression MOD unary_expression
{
$$ = clc_create_binary_expression(MOD_EXPRESSION, $1, $3);
}
;
unary_expression
: postfix_expression
| SUB unary_expression
{
$$ = clc_create_minus_expression($2);
}
;
postfix_expression
: primary_expression
;
primary_expression
: IDENTIFIER LP expression_list RP
{
$$ = clc_create_function_call_expression($1, $3);
}
| IDENTIFIER LP RP
{
$$ = clc_create_function_call_expression($1, NULL);
}
| if_expression
| while_expression
| LP expression RP
{
$$ = $2;
}
| IDENTIFIER
{
$$ = clc_create_identifier_expression($1);
}
| INT_LITERAL
| DOUBLE_LITERAL
;
if_expression /*if文宣言*/
: IF expression LC expression_list RC
{
$$ = clc_create_if_expression($2, $4, NULL);
}
| IF expression LC expression_list RC ELSE LC expression_list RC
{
$$ = clc_create_if_expression($2, $4, $8);
}
;
while_expression /*while文宣言*/
: WHILE expression LC expression_list RC
{
$$ = clc_create_while_expression($2, $4);
}
;
%%
/****create.c****/
void
clc_function_define(char *identifier, ParameterList *parameter_list,
Expression *expression_list)
{
FunctionDefinition *f;
if (clc_search_function(identifier)) {
clc_compile_error(FUNCTION_MULTIPLE_DEFINE_ERR, "(%s)\n", identifier);
clc_reopen_current_storage();
return;
}
f = clc_malloc(sizeof(FunctionDefinition));
f->name = identifier;
f->parameter = parameter_list;
f->expression_list = expression_list;
f->storage = clc_current_interpreter->current_storage;
clc_current_interpreter->current_storage = MEM_open_storage(0);
f->next = clc_current_interpreter->function_list;
clc_current_interpreter->function_list = f;
}
ParameterList*
clc_create_parameter(char *identifier)
{
ParameterList *p;
p = clc_malloc(sizeof(ParameterList));
p->name = identifier;
p->next = NULL;
return p;
}
ParameterList *
chain_parameter(ParameterList *list, ParameterList *add)
{
ParameterList *pos;
for (pos = list; pos->next; pos = pos->next)
;
pos->next = add;
return list;
}
ParameterList*
clc_chain_parameter(ParameterList *list, char *identifier)
{
ParameterList *add;
add = clc_create_parameter(identifier);
return chain_parameter(list, add);
}
Expression *
clc_alloc_expression(ExpressionType type)
{
Expression *exp;
exp = clc_malloc(sizeof(Expression));
exp->type = type;
return exp;
}
Expression *
clc_create_expression_list(Expression *expression)
{
Expression *exp;
exp = clc_alloc_expression(EXPRESSION_LIST_EXPRESSION);
exp->u.expression_list.expression = expression;
exp->u.expression_list.next = NULL;
return exp;
}
Expression *
clc_chain_expression_list(Expression *list, Expression *add)
{
Expression *exp;
Expression *pos;
exp = clc_alloc_expression(EXPRESSION_LIST_EXPRESSION);
exp->u.expression_list.expression = add;
exp->u.expression_list.next = NULL;
for (pos = list; pos->u.expression_list.next;
pos = pos->u.expression_list.next)
;
pos->u.expression_list.next = exp;
return list;
}
Expression *
clc_create_assign_expression(char *variable,
Expression *operand)
{
Expression *exp;
exp = clc_alloc_expression(ASSIGN_EXPRESSION);
exp->u.assign_expression.variable = variable;
exp->u.assign_expression.operand = operand;
return exp;
}
static Expression
convert_value_to_expression(Value *v)
{
Expression expr;
if (v->type == INT_VALUE) {
expr.type = INT_EXPRESSION;
expr.u.int_value = v->u.int_value;
} else {
DBG_assert(v->type == DOUBLE_VALUE, ("v->type..%d\n", v->type));
expr.type = DOUBLE_EXPRESSION;
expr.u.double_value = v->u.double_value;
}
return expr;
}
Expression *
clc_create_binary_expression(ExpressionType operator,
Expression *left,
Expression *right)
{
if ((left->type == INT_EXPRESSION
|| left->type == DOUBLE_EXPRESSION)
&& (right->type == INT_EXPRESSION
|| right->type == DOUBLE_EXPRESSION)) {
Value v;
v = clc_eval_binary_expression(NULL, operator, left, right);
/* Overwriting left hand expression. */
*left = convert_value_to_expression(&v);
return left;
} else {
Expression *exp;
exp = clc_alloc_expression(operator);
exp->u.binary_expression.left = left;
exp->u.binary_expression.right = right;
return exp;
}
}
Expression *
clc_create_minus_expression(Expression *operand)
{
if (operand->type == INT_EXPRESSION
|| operand->type == DOUBLE_EXPRESSION) {
Value v;
v = clc_eval_minus_expression(NULL, operand);
/* Notice! Overwriting operand expression. */
*operand = convert_value_to_expression(&v);
return operand;
} else {
Expression *exp;
exp = clc_alloc_expression(MINUS_EXPRESSION);
exp->u.minus_expression = operand;
return exp;
}
}
Expression *
clc_create_identifier_expression(char *identifier)
{
Expression *exp;
exp = clc_alloc_expression(IDENTIFIER_EXPRESSION);
exp->u.identifier = identifier;
return exp;
}
Expression *
clc_create_if_expression(Expression *condition,
Expression *then_expression,
Expression *else_expression)
{
Expression *exp;
exp = clc_alloc_expression(IF_EXPRESSION);
exp->u.if_expression.condition = condition;
exp->u.if_expression.then_expression = then_expression;
exp->u.if_expression.else_expression = else_expression;
return exp;
}
Expression *
clc_create_while_expression(Expression *condition,
Expression *expression)
{
Expression *exp;
exp = clc_alloc_expression(WHILE_EXPRESSION);
exp->u.while_expression.condition = condition;
exp->u.while_expression.expression_list = expression;
return exp;
}
Expression *
clc_create_function_call_expression(char *func_name,
Expression *argument)
{
Expression *exp;
exp = clc_alloc_expression(FUNCTION_CALL_EXPRESSION);
exp->u.function_call_expression.identifier = func_name;
exp->u.function_call_expression.argument = argument;
return exp;
}