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

📄 yabasic.c

📁 基于vc++语言的 basic 语言的编译器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    break;
  }
#elif WINDOWS
  GetConsoleMode(ConsoleInput,&oflags);
  flags=oflags&~(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT);
  SetConsoleMode(ConsoleInput,flags);
  skey="";
  if (ms==0) {
    PeekConsoleInput(ConsoleInput,&inrec,1,&num);
    if (num==0) goto keydone;
    ReadConsoleInput(ConsoleInput,&inrec,1,&num);
    if (!is_valid_key(&inrec)) goto keydone;
  }
  else if (ms>0) {
    end=GetTickCount()+ms;
    do {	
      now=GetTickCount();
      left=end-now;
      if (left>0) {
	ret=WaitForSingleObject(ConsoleInput,left);
	if (ret==WAIT_OBJECT_0) ReadConsoleInput(ConsoleInput,&inrec,1,&num);
      }
    } while(left>0 && ret==WAIT_OBJECT_0 && !is_valid_key(&inrec));
    if (left<=0 || ret!=WAIT_OBJECT_0) goto keydone;
  }
  else { /* if (ms<0) */
    do {
      ReadConsoleInput(ConsoleInput,&inrec,1,&num);
    } while(!is_valid_key(&inrec));	
  }
  skey=keybuff;
  if (isprint(inrec.Event.KeyEvent.uChar.AsciiChar)) {
    keybuff[0]=inrec.Event.KeyEvent.uChar.AsciiChar;
    keybuff[1]='\0';
  }
  else {
    key=inrec.Event.KeyEvent.wVirtualKeyCode;
    switch(key) {
    case 0x1b: skey="esc";break;
    case 0x0d: skey="enter";break;
    case 0x09: skey="tab";break;
    case 0x21: skey="scrnup";break;
    case 0x22: skey="scrndown";break;
    case 0x70: skey="f1";break;
    case 0x71: skey="f2";break;
    case 0x72: skey="f3";break;
    case 0x73: skey="f4";break;
    case 0x74: skey="f5";break;
    case 0x75: skey="f6";break;
    case 0x76: skey="f7";break;
    case 0x77: skey="f8";break;
    case 0x78: skey="f9";break;
    case 0x79: skey="f10";break;
    case 0x7a: skey="f11";break;
    case 0x7b: skey="f12";break;
    case 0x24: skey="home";break;
    case 0x23: skey="end";break;
    case 0x2d: skey="ins";break;
    case 0x2e: skey="del";break;
    case 0x08: skey="backspace";break;
    case 0x27: skey="right";break;
    case 0x25: skey="left";break;
    case 0x28: skey="down";break;
    case 0x26: skey="up";break;
    default:
      sprintf(keybuff,"key%02x",key);
    }
  }
 keydone:
  SetConsoleMode(ConsoleInput,oflags);
#endif
  return my_strdup(skey);
}

#ifdef WINDOWS	
int is_valid_key(INPUT_RECORD *rec) /* check if input rec contains valid key */
{
  if (rec->EventType!=KEY_EVENT || 
      !rec->Event.KeyEvent.bKeyDown ||
      rec->Event.KeyEvent.wVirtualKeyCode==VK_SHIFT ||
      rec->Event.KeyEvent.wVirtualKeyCode==VK_CONTROL) {
    return FALSE;
  }
  return TRUE;
}
#endif		
		

void create_openwin(int fnt) /* create Command 'openwin' */
{
  struct command *cmd;
	
  cmd=add_command(cOPENWIN);
  cmd->args=fnt;
}


void openwin(struct command *cmd) /* open a Window */
{
  int fnt;
  static int first=TRUE; /* flag to decide if initialization is necessary */
#ifdef UNIX
  static XEvent event; /* what has happened ? */
  XSetWindowAttributes attrib; /* properties of window */
#endif
	
  if (winopened) {
    error(WARNING,"Window already open");
    return;
  }
	
  fnt=cmd->args;
  if (fnt) font=my_strdup(pop()->pointer);
	
  winheight=(int)pop()->value;
  if (winheight<1) {
    error(ERROR,"winheight less than 1 pixel");
    return;
  }
	
  winwidth=(int)pop()->value;
  if (winwidth<1) {
    error(ERROR,"winwidth less than 1 pixel");
    return;
  }
	
  /* initialize grafics */
  if (first && !grafinit()) return;
	
#ifdef UNIX
	
  /* create the window */
  /*  window=XCreateSimpleWindow(display,root,winx,winy,winwidth,winheight,
      0,0,b_colour); */

  attrib.backing_store=Always;
  attrib.save_under=TRUE;
  attrib.background_pixel=b_colour;
  window=XCreateWindow(display,root,winx,winy,winwidth,winheight,0,
		       CopyFromParent,CopyFromParent,CopyFromParent,
		       CWBackingStore|CWSaveUnder|CWBackPixel,
		       &attrib);

  if (window==None) {
    error(ERROR,"Could not create window");
    return;
  }

  /* put in name for the window */
  XStoreName(display,window,progname);
	
  /* set size hints */
  XSetWMNormalHints(display,window,&sizehints);
	
  /* display it */
  XMapWindow(display,window);
	
  /* wait for exposure */
  XSelectInput(display,window,0xffffff);
  XFlush(display);
  do {
    XNextEvent(display,&event);
  } while(event.type!=VisibilityNotify);
  XSelectInput(display,window,0);
	
#else /* WINDOWS */
	
  if (wtevent==INVALID_HANDLE_VALUE) wtevent=CreateEvent(NULL,FALSE,FALSE,"winevent");
  ResetEvent(wtevent);
  /* create thread to care for window */
  wthandle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)winthread,
			     0,0,(LPDWORD)&wtid);
  if (wthandle==NULL) {
    error(ERROR,"can't create thread for window");
    return;
  }
	
  WaitForSingleObject(wtevent,INFINITE);
  	
#endif
  first=FALSE;
  winopened=TRUE;
  calc_psscale();
}


int grafinit(void)  /* initialize grafics (either X or WIN95) */
{
	
#ifdef UNIX
  static int screen; /* Number of Screen on Display */
  static XColor asked,got; /* color is complex ... */
  static Colormap map; /* my color map */
  static XGCValues xgcvalues; /* Values for Graphics Context */
  static unsigned int w,h; /* width and height of window */
#elif WINDOWS
  int n;
  int f; /* int-value of font */
  char *family; /* font family */
#endif
	
#ifdef UNIX
	
  /* get display */
  display=XOpenDisplay(displayname);
  if (display==NULL) {
    error(ERROR,"Can't open Display");
    return FALSE;
  }
    
  /* get screen */
  screen=DefaultScreen(display);
  root=RootWindow(display,screen);
	
  /* care for colors */
  if (DefaultDepth(display,screen)==1) {  /* BW-Screen ? */
    f_colour=BlackPixel(display,screen);
    b_colour=WhitePixel(display,screen); }
  else {
    map=DefaultColormap(display,screen);
    if (foreground==NULL) 
      foreground=XGetDefault(display,"yabasic","foreground");
    if (foreground==NULL) foreground="black";
		
    if (!XAllocNamedColor(display,map,foreground,&got,&asked)) {
      sprintf(string,"could not get fg-color '%s', trying 'black' instead",
	      foreground);
      error(WARNING,string);
      if (!XAllocNamedColor(display,map,"black",&got,&asked)) {
	error(ERROR,"could not get it");
	return FALSE;
      }
    }
    f_colour=got.pixel;
		
    if (background==NULL) 
      background=XGetDefault(display,"yabasic","background");
    if (background==NULL) background="white";
    if (!XAllocNamedColor(display,map,background,&got,&asked)) {
      sprintf(string,"could not get bg-color '%s', trying 'white' instead",
	      background);
      error(WARNING,string);
      if (!XAllocNamedColor(display,map,"white", &got,&asked)) {
	error(ERROR,"could not get it");
	return FALSE;
      }
    }
    b_colour=got.pixel;
  }
	
  /* get size hints */
  if (geometry==NULL) geometry=XGetDefault(display,"yabasic","geometry");
  XParseGeometry(geometry,&winx,&winy,&w,&h);
  sizehints.x=winx;
  sizehints.y=winy;
  sizehints.flags=USPosition;
	
  /* get font height */
  if (!font) font=XGetDefault(display,"yabasic","font");
  if (!font) font="6x10";
  myfont=XLoadQueryFont(display,font);
  if (!myfont) {
    sprintf(string,"could not load font '%s', trying 'fixed' instead",font);
    error(WARNING,string);
    myfont=XLoadQueryFont(display,"fixed");
    if (!myfont) {
      error(ERROR,"could not get it");
      return FALSE;
    }
  }
  xgcvalues.font=myfont->fid;
  fontheight=myfont->ascent;
    
  /* create graphics context, accept defaults ... */
  xgcvalues.foreground=f_colour;
  xgcvalues.background=b_colour;
  gc=XCreateGC(display,root,GCForeground|GCBackground|GCFont,&xgcvalues);
  /* create graphics context for reverse drawing */
  xgcvalues.foreground=b_colour;
  xgcvalues.background=f_colour;
  rgc=XCreateGC(display,root,GCForeground|GCBackground,&xgcvalues);
	
#elif WINDOWS
	
  /* choose font */
  if (!font) font=getreg("font");
  if (!font) font="swiss13";
  f=FF_SWISS;
  fontheight=13;    
    
  family=my_strdup(font);
  for(n=0;*(family+n)!='\0' && !isdigit(*(family+n));n++)
    *(family+n)=tolower((int)*(family+n));
  if (isdigit(*(family+n))) sscanf(family+n,"%d",&fontheight);
  *(family+n)='\0';
    
  if (!strcmp("decorative",family)) f=FF_DECORATIVE;
  else if (!strcmp("dontcare",family)) f=FF_DONTCARE;
  else if (!strcmp("modern",family)) f=FF_MODERN;
  else if (!strcmp("roman",family)) f=FF_ROMAN;
  else if (!strcmp("script",family)) f=FF_SCRIPT;
  else if (!strcmp("swiss",family)) f=FF_SWISS;
  else {
    sprintf(string,"Don't know font '%s' using 'swiss' instead",font);
    error(WARNING,string);
    f=FF_SWISS;
  }
    
  logfont.lfHeight=-fontheight;
  logfont.lfWidth=0;
  logfont.lfEscapement=0;
  logfont.lfOrientation=0;
  logfont.lfWeight=FW_DONTCARE;
  logfont.lfItalic=FALSE;
  logfont.lfUnderline=FALSE;
  logfont.lfStrikeOut=FALSE;
  logfont.lfCharSet=DEFAULT_CHARSET;
  logfont.lfOutPrecision=OUT_DEFAULT_PRECIS;
  logfont.lfClipPrecision=CLIP_DEFAULT_PRECIS;
  logfont.lfQuality=DEFAULT_QUALITY;
  logfont.lfPitchAndFamily=DEFAULT_PITCH | f;
  logfont.lfFaceName[0]='\0';
  myfont=CreateFontIndirect(&logfont);
	
  if (myfont==NULL) {
    sprintf(string,"Could not create font '%s' for screen",font);
    error(ERROR,string);
    return FALSE;
  }
#endif
  return TRUE;
}

void calc_psscale()  /* calculate scale-factor for postscript */
{
  if ((float)winwidth/winheight>(float)18/25)
    psscale=18*0.39*72/winwidth;
  else
    psscale=25*0.39*72/winheight;
}


void dot() /* draw a dot */
{
  double x,y;
	
  y=pop()->value;
  x=pop()->value;
  transform(&x,&y);
  if (!winopened) {
    error(ERROR,"Got no window to draw");
    return;
  }
#ifdef UNIX
  XDrawPoint(display,window,gc,x,y);
  XFlush(display);
  if (printerfile) {
    fprintf(printerfile,"%g %g D\n",
            (x-0.5)*psscale,(winheight-y+0.5)*psscale);
  }
#elif WINDOWS
  startdraw();
  SetPixelV(devcon,(int)x,(int)y,RGB(0,0,0));
  SetPixelV(bitcon,(int)x,(int)y,RGB(0,0,0));
  if (printer) {
    MoveToEx(printer,(int)(x*prnscale+prnoff),(int)(y*prnscale+prnoff),NULL);
    LineTo(printer,(int)(x*prnscale+prnoff),(int)(y*prnscale+prnoff));
  }
  ReleaseDC(window,devcon);
#endif
}


void create_line(char flag) /* create Command 'line' */
{
  struct command *cmd;
	
  cmd=add_command(cLINE);
  cmd->tag=flag;
}


void line(struct command *cmd) /* draw a line */
{
  double x1,y1,x2,y2;
  double nx,ny,px,py,norm;
  int arrow;
  static double lastx,lasty;
  static int lastvalid=FALSE;
	
  if (!winopened) {
    error(ERROR,"Got no window to draw");
    return;
  }
	
  if (cmd->tag=='n') {
    lastvalid=FALSE;
    return;
  }
  arrow=(cmd->tag=='a');
  y2=pop()->value;
  x2=pop()->value;
  if (cmd->tag=='t') {
    if (!lastvalid) {
      lastx=x2;
      lasty=y2;
      lastvalid=TRUE;
      return;
    }
    y1=lasty;
    x1=lastx;
  }
  else {
    y1=pop()->value;
    x1=pop()->value;
  }
  lastx=x2;
  lasty=y2;
  transform(&x1,&y1);
  transform(&x2,&y2);
	
  if (arrow) {
    px=x2-x1;
    py=y2-y1;
    nx=py;
    ny=-px;
    norm=sqrt(nx*nx+ny*ny);
    nx*=0.4*fontheight/norm;
    ny*=0.4*fontheight/norm;
    px*=0.8*fontheight/norm;
    py*=0.8*fontheight/norm;
  }
	
  do_line(x1,y1,x2,y2);
  if (arrow) {
    do_line(x2,y2,x2-px+nx,y2-py+ny);
    do_line(x2,y2,x2-px-nx,y2-py-ny);
  }
}


void do_line(double x1,double y1,double x2,double y2) /* draw a line */
{
#ifdef UNIX
  XDrawLine(display,window,gc,x1,y1,x2,y2);
  XFlush(display);
  if(printerfile) {
    fprintf(printerfile,"N\n");
    fprintf(printerfile,"%g %g M\n",
            x1*psscale,(winheight-y1)*psscale);
    fprintf(printerfile,"%g %g L S\n",
            x2*psscale,(winheight-y2)*psscale);
  }
  fflush(printerfile);
#elif WINDOWS
  startdraw();
  MoveToEx(devcon,(int)x1,(int)y1,NULL);
  LineTo(devcon,(int)x2,(int)y2);
  MoveToEx(bitcon,(int)x1,(int)y1,NULL);
  LineTo(bitcon,(int)x2,(int)y2);
  if (printer) {
    MoveToEx(printer,(int)(x1*prnscale+prnoff),(int)(y1*prnscale+prnoff),NULL);
    LineTo(printer,(int)(x2*prnscale+prnoff),(int)(y2*prnscale+prnoff));
  }
  ReleaseDC(window,devcon);
#endif
}


void circle() /* draw a circle */
{
  double x,y,r;
	
  r=pop()->value;
  y=pop()->value;
  x=pop()->value;
  transform(&x,&y);
  if (!winopened) {
    error(ERROR,"Got no window to draw");
    return;
  }
  do_circle(x,y,r);
}


void do_circle(double x,double y,double r) /* actually draw the circle */
{
#ifdef UNIX
  XDrawArc(display,window,gc,x-r,y-r,2*r,2*r,0*64,360*64);
  XFlush(display);
  if(printerfile) {
    fprintf(printerfile,"N\n");
    fprintf(printerfile,"%g %g %g C S\n",
            x*psscale,(winheight-y)*psscale,r*psscale);
    fflush(printerfile);
  }
#else /* WINDOWS */
  startdraw();
  Arc(devcon,(int)(x-r),(int)(y-r),(int)(x+r),(int)(y+r),0,0,0,0);
  Arc(bitcon,(int)(x-r),(int)(y-r),(int)(x+r),(int)(y+r),0,0,0,0);
  if (printer) {
    Arc(printer,(int)((x-r)*prnscale+prnoff),(int)((y-r)*prnscale+prnoff),
	(int)((x+r)*prnscale+prnoff),(int)((y+r)*prnscale+prnoff),0,0,0,0); 
  }
  ReleaseDC(window,devcon);
#endif
}


void create_text(int has_alignement) /* create Command 'text' */
{
  struct command *cmd;
	
  cmd=add_command(cTEXT);
  cmd->args=has_alignement;
}


void text(struct command *cmd) /* write a text */
{
  double x,y;
  char *text,*alignement;
	
  if (cmd->args) {
    alignement=pop()->pointer;
    if (!check_alignement(alignement)) return;
  }    
  else {
    alignement=text_align;
  }
  text=pop()->pointer;
  y=pop()->value;
  x=pop()->value;
  transform(&x,&y);
  if (!winopened) {
    error(ERROR,"Got no window to draw");
    return;
  }
  do_text((int)x,(int)y,text,alignement);
}


int check_alignement(char *al) /* checks, if text-alignement is valid */
{
  al[0]=tolower((int)al[0]);
  al[1]=tolower((int)

⌨️ 快捷键说明

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