modular ops (untested)
This commit is contained in:
		
							parent
							
								
									92f13c8e30
								
							
						
					
					
						commit
						efa6fe674f
					
				
							
								
								
									
										90
									
								
								src/ops.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/ops.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,90 @@
 | 
				
			|||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "blang.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* no-op */
 | 
				
			||||||
 | 
					void Ops_bang(struct State *s){
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Ops_dollar(struct State *s){
 | 
				
			||||||
 | 
						s->chart = (char *)0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Ops_percent(struct State *s){
 | 
				
			||||||
 | 
						*(s->chart) = s->hand;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Ops_carat(struct State *s){
 | 
				
			||||||
 | 
						s->state = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Ops_ampersand(struct State *s){
 | 
				
			||||||
 | 
						s->hand = s->chart;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Ops_plus(struct State *s){
 | 
				
			||||||
 | 
						++(s->state);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Ops_dash(struct State *s){
 | 
				
			||||||
 | 
						--(s->state);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Ops_right(struct State *s){
 | 
				
			||||||
 | 
						putc((char)s->state, stdout);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Ops_left(struct State *s){
 | 
				
			||||||
 | 
						s->state = getc(stdin);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Ops_semi(struct State *s){
 | 
				
			||||||
 | 
						while(
 | 
				
			||||||
 | 
							(c = getc(stdin)) != EOF
 | 
				
			||||||
 | 
							&& strchr("!\n", c) == NULL
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Ops_cross(struct State *s){
 | 
				
			||||||
 | 
						char *i;
 | 
				
			||||||
 | 
						i = s->chart;
 | 
				
			||||||
 | 
						s->chart = (char *)s->hand;
 | 
				
			||||||
 | 
						s->hand = (unsigned char)i;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct {
 | 
				
			||||||
 | 
						unsigned char name;
 | 
				
			||||||
 | 
						void (*f)(struct State *);
 | 
				
			||||||
 | 
					} *OPS[] = {
 | 
				
			||||||
 | 
						{ '$', Ops_dollar },
 | 
				
			||||||
 | 
						{ '%', Ops_percent },
 | 
				
			||||||
 | 
						{ '^', Ops_caret },
 | 
				
			||||||
 | 
						{ '&', Ops_ampersand },
 | 
				
			||||||
 | 
						{ '*', Ops_splat },
 | 
				
			||||||
 | 
						{ '+', Ops_plus },
 | 
				
			||||||
 | 
						{ '-', Ops_dash },
 | 
				
			||||||
 | 
						{ '>', Ops_right },
 | 
				
			||||||
 | 
						{ '<', Ops_left },
 | 
				
			||||||
 | 
						{ 'x', Ops_cross },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* no-ops */
 | 
				
			||||||
 | 
						{ '!', Ops_bang },
 | 
				
			||||||
 | 
						{ ' ', Ops_bang },
 | 
				
			||||||
 | 
						{ '\n', Ops_bang },
 | 
				
			||||||
 | 
						{ '\r', Ops_bang },
 | 
				
			||||||
 | 
						{ '\t', Ops_bang },
 | 
				
			||||||
 | 
						{ '\v', Ops_bang }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Slower than a switch but you don't have to update it when you add new
 | 
				
			||||||
 | 
					 * ops! */
 | 
				
			||||||
 | 
					(void(struct State *)) Ops_lookup(char op){
 | 
				
			||||||
 | 
						size_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for(i = 0; i < (sizeof OPS)/(sizeof *OPS); ++i)
 | 
				
			||||||
 | 
							if(op == OPS[i].name)
 | 
				
			||||||
 | 
								return OPS[i].f;
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user