⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cal.c

📁 redboy for gba 是BPNS为GBA编写的一个小软件。软件的邹形是BASIC高级语言解释执行器。几经修改和扩展
💻 C
字号:
#include <CsAgb.h>
#include <rb_var.h>
#include <rbasic.h>
#include <math.h>
#include <timer.h>
#include <rmath.h>
#include <rb_stdio.h>
#include <rb_file.h>
#include <rb_string.h>

#define bg_id 128
#define mVRAM (u16 *) 0x06000000

double rb_cal(char *exp);

extern void rb_get_str(char *exp,char *str);
extern u8 get_para(char *exp,double *nump,char *strp,char *tp);
extern double cal_def_fun(u8 id,char *exp);
extern double rb_calcu1(char *exp);
u8 is_brac(char ch)//是括号
{
   return (ch=='(' || ch==')');
}
int sgn(double x)
{
   if (x>0.0) return 1;
   else if (x<0.0) return -1;
   return 0;
}
u8 peek(u16 loc)
{
   if (loc>2048 || loc<1)
   {
      rb_error=13;
      return 0;
   }
   return rb_peek_M[loc];
}

u8 rb_getkey(u8 fla)//获得健值
{
   u8 count=0;
   u8 key=0;
   fla=fla?1:0;
   while (TRUE)
   {
      CS_ReadKey();
      if (CS_IsKeyDown(KEY_UP)) key=1;
      else if (CS_IsKeyDown(KEY_DOWN)) key=2;
      else if (CS_IsKeyDown(KEY_LEFT)) key=3;
      else if (CS_IsKeyDown(KEY_RIGHT)) key=4;
      else if (CS_IsKeyDown(KEY_L)) key=5;
      else if (CS_IsKeyDown(KEY_R)) key=6;
      else if (CS_IsKeyDown(KEY_START)) key=7;
      else if (CS_IsKeyDown(KEY_SELECT)) key=8;
      else if (CS_IsKeyDown(KEY_A)) key=9;
      else if (CS_IsKeyDown(KEY_B)) key=10;
      count+=fla;
      if (count>20 || key) return key;
   }
}
double rb_getpet(char *exp)
{
   double num[2];
   if (get_para(exp,num,NULL,"2NN")) return 0.0;
   if (num[0]<0 || num[0]>239 || num[1]<0 || num[1]>159)
   {
      rb_error=12;
      return 0.0;
   }
   return *(mVRAM+(int)num[0]+240*(int)num[1]);
}

double rb_max(char *exp)
{
   double num[2];
   if (get_para(exp,num,NULL,"2NN")) return 0.0;
   return (num[0]>num[1])?num[0]:num[1];
}

double rb_min(char *exp)
{
   double num[2];
   if (get_para(exp,num,NULL,"2NN")) return 0.0;
   return (num[0]<num[1])?num[0]:num[1];
}

double rb_var(char *exp)
{
   double *dp;
   int *ip;
   switch(exp[0])
   {
      case 'f':
         if (rb_float_dim_indx[exp[1]-bg_id]==0)
         {
            rb_error=4;
            return 0.0;
         }
         return var(rb_float_dim[exp[1]-bg_id],rb_float_dim_indx[exp[1]-bg_id]);
      case 'i':
         if (rb_int_dim_indx[exp[1]-bg_id]==0)
         {
            rb_error=4;
            return 0.0;
         }
         return var_int(rb_int_dim[exp[1]-bg_id],rb_int_dim_indx[exp[1]-bg_id]);
      default:
         rb_error=22;
         return 0.0;
   }
}
double rb_aver(char *exp)
{
   double *dp;
   int *ip;
   switch(exp[0])
   {
      case 'f':
         if (rb_float_dim_indx[exp[1]-bg_id]==0)
         {
            rb_error=4;
            return 0.0;
         }
         return aver(rb_float_dim[exp[1]-bg_id],rb_float_dim_indx[exp[1]-bg_id]);
      case 'i':
         if (rb_int_dim_indx[exp[1]-bg_id]==0)
         {
            rb_error=4;
            return 0.0;
         }
         return aver_int(rb_int_dim[exp[1]-bg_id],rb_int_dim_indx[exp[1]-bg_id]);
      default:
         rb_error=22;
         return 0.0;
   }
}
u16 rb_rgb(char *exp)
{
   double num[3];
   if (get_para(exp,num,NULL,"3NNN")) return 0;
   return RGB((u8)num[0],(u8)num[1],(u8)num[2]);
}

u8 rb_eof(char *exp)
{
   u8 id;
   if (exp[0]!='#')
   {
      rb_error=6;
      return 0;
   }
   id=rb_cal(exp+1);
   return rb_feof(id);
}
u32 rb_tell(char *exp)
{
   u8 id;
   if (exp[0]!='#')
   {
      rb_error=6;
      return 0;
   }
   id=rb_cal(exp+1);
   return rb_ftell(id);
}
u8 rb_len(char *exp)
{
   char temp[str_max_len];
   rb_get_str(exp,temp);
   return str_len(temp);
}
double rb_val(char *exp)
{
   char temp[str_max_len];
   rb_get_str(exp,temp);
   return str_to_num(temp);
}
u8 rb_instr(char *exp)
{
   char temp[2*str_max_len];
   if (get_para(exp,NULL,temp,"2SS")) return 0;
   return str_find(temp,temp+str_max_len);
}
u8 rb_asc(char *exp)
{
   char temp[str_max_len];
   rb_get_str(exp,temp);
   return temp[0];
}
int rb_cmp(char *exp)
{
   char temp[2*str_max_len];
   if (get_para(exp,NULL,temp,"2SS")) return 0;
   return strcmp(temp,temp+str_max_len);
}

double get_math_fun(u8 id,double x)
{
   switch (id)
   {
      case 0:
         return sin(x);
      case 1:
         return cos(x);
      case 2:
         return tan(x);
      case 3:
         if (x<=0.0)
         {
            rb_error=12;
            return 0.0;
         }
         return log10(x);
      case 4:
         if (x<=0.0)
         {
            rb_error=12;
            return 0.0;
         }
         return log(x);
      case 5:
         return pow(10.0,x);
      case 6:
         return exp(x);
      case 7:
         if (x<0.0)
         {
            rb_error=12;
            return 0.0;
         }
         return sqrt(x);
      case 8:
         return abs(x);
      case 9:
         return sgn(x);
      case 10:
         return (int)x;
      case 11:
         if (x<-1.0 || x>1.0)
         {
            rb_error=12;
            return 0.0;
         }
         return asin(x);
      case 12:
         if (x<-1.0 || x>1.0)
         {
            rb_error=12;
            return 0.0;
         }
         return acos(x);
      case 13:
         return atan(x);
      case 14:
         return sinh(x);
      case 15:
         return cosh(x);
      case 16:
         return tanh(x);
      case 17:
         return rnd(x);
      case 18:
         return get_time()-x;
      case 19:
         if (x<1.0 || x>2048.0)
         {
            rb_error=13;
            return 0.0;
         }
         return peek(x);
      case 20:
         return rb_yp;
      case 21:
         return rb_yp;
      case 22:
         return rb_bg;
      case 23:
         return rb_co;
      default:
         return 0.0;
   }
}

double cal_math_fun(u8 id,char *exp)
{
   if (id<24) return get_math_fun(id,rb_cal(exp));
   else if (id==24) return rb_getpet(exp);
   else if (id==25) return rb_getkey(rb_cal(exp));
   else
   {
      switch(id)
      {
         case 26:
            return rb_max(exp);
         case 27:
            return rb_min(exp);
         case 28:
            return rb_var(exp);
         case 29:
            return rb_aver(exp);
         case 30:
            return rb_rgb(exp);
         case 31:
            return rb_eof(exp);
         case 32:
            return rb_tell(exp);
         case 33:
            return rb_len(exp);
         case 34:
            return rb_val(exp);
         case 35:
            return rb_instr(exp);
         case 36:
            return rb_asc(exp);
         case 37:
            return rb_cmp(exp);
         case 38:
            return rb_calcu1(exp);
         default:
            rb_error=6;
      }
   }
   return 0.0;
}

u8 is_opt(char ch)
{
   u8 i=0;
   static char opts[]="+-*/%^";
   while (opts[i]!='\0')
   {
      if (ch==opts[i]) return i+1;
      i++;
   }
   return 0;
}

double rb_mod(double x,double y)
{
   int num;
   if (y==0.0)
   {
      rb_error=14;
      return 0.0;
   }
   num=(int)(x/y);
   return x-y*num;
}
   
double std_cal(double x,double y,u8 op)//基本运算
{
   switch (op)
   {
      case 1://+
      return x+y;
      case 2://-
      return x-y;
      case 3://*
      return x*y;
      case 4:// /
      if (y==0.0)
      {
         rb_error=14;
         return 0.0;
      }
      return x/y;
      case 5://%
      return rb_mod(x,y);
      case 6://^
      return pow(x,y);
      default:
      return 0.0;
   }
}
u8 get_pstr(char lp,char rp,char *exp,char *sv)
{
   int inis=1;
   int ep=0,sp=0;
   int flg=1;
   while (flg && exp[ep]!='\0')
   {
      if (exp[ep]=='\"') inis=!inis;
      if (inis)
      {
         if (exp[ep]==lp) flg++;
         else if (exp[ep]==rp) flg--;
      }
      sv[sp]=exp[ep];
      sp++;
      ep++;
   }
   if (flg) return 0;
   sv[sp-1]='\0';
   return sp;
}

double rb_cal(char *exp)
{
   double val[5];
   char opts[5];
   static int weight[]={0,1,1,2,2,2,3};
   char temp[str_max_len];
   int vp=0,op=0,tp=0,ep=0;
   int opt=0;
   int flg;
   int i;
   while (exp[ep]!='\0')
   {
      opt=is_opt(exp[ep]);
      if (opt)
      {
         if (vp==0 || op+1!=vp)//语法错误
         {
            rb_error=6;
            return 0.0;
         }
         while (op)
         {
            if (weight[opt]<=weight[opts[op-1]])//可先行运算
            {
               vp--;
               op--;
               val[vp-1]=std_cal(val[vp-1],val[vp],opts[op]);
            }
            else break;
         }
         opts[op]=opt;
         op++;
         ep++;
      }
      else if(is_number(exp[ep]))//数字
      {
         tp=0;
         while (exp[ep]!='\0' && !is_opt(exp[ep]) && !is_brac(exp[ep]))
         {
            temp[tp]=exp[ep];
            ep++;
            tp++;
         }
         temp[tp]='\0';
         val[vp]=str_to_num(temp);
         if (vp!=op)
         {
            rb_error=6;
            return 0;
         }
         vp++;
      }
      else
      {
         if (exp[ep]=='i' || exp[ep]=='f')//数组处理
         {
            tp=0;
            opt=ep;
            ep+=3;
            flg=get_pstr('[',']',exp+ep,temp);
            if (flg==0)
            {
               rb_error=6;
               return 0.0;
            }
            ep=ep+flg;
            if (exp[opt]=='f') val[vp]=get_float_dim_val(exp[opt+1]-bg_id,rb_cal(temp));
            else val[vp]=get_int_dim_val(exp[opt+1]-bg_id,rb_cal(temp));
         }
         else if (exp[ep]=='M' || exp[ep]=='D')//数字函数与自定义函数
         {
            tp=0;
            opt=ep;
            ep+=3;
            flg=get_pstr('(',')',exp+ep,temp);
            if (flg==0)
            {
               rb_error=6;
               return 0.0;
            }
            ep+=flg;
            if (exp[opt]=='M') val[vp]=cal_math_fun(exp[opt+1]-bg_id,temp);
            else val[vp]=cal_def_fun(exp[opt+1]-bg_id,temp);
         }
         else if(exp[ep]=='I')
         {
            ep++;
            val[vp]=get_int_val(exp[ep]-bg_id);
            ep++;
         }
         else if (exp[ep]=='F')
         {
            ep++;
            val[vp]=get_float_val(exp[ep]-bg_id);
            ep++;
         }
         else if (exp[ep]=='(')
         {
            ep++;
            flg=get_pstr('(',')',exp+ep,temp);
            //RBprint(temp);
            if (flg==0)
            {
               rb_error=6;
               return 0.0;
            }
            ep+=flg;
            val[vp]=rb_cal(temp);
         }
         else
         {
            rb_error=6;
            return 0.0;
         }
         if (vp!=op)
         {
            rb_error=6;
            return 0.0;
         }
         vp++;
      }
   }
   i=vp-1;
   while (i>0)
   {
      val[i-1]=std_cal(val[i-1],val[i],opts[i-1]);
      i--;
   }
   return val[0];
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -