(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; }