s502 assembler
A very simple assembler for the 6502 line of processors written in C
state.c
Go to the documentation of this file.
1 #include "debugmalloc.h"
2 
3 #include <stdlib.h>
4 #include <string.h>
5 
6 #include "state.h"
7 #include "logging.h"
8 
17  State* ret = (State*)malloc(sizeof(State));
18 
19  if (ret == NULL) {
20  ERROR("Memory allocation error in state_new()");
21  return NULL;
22  }
23 
24  if ((ret->defines = map_new()) == NULL) goto ERR;
25  if ((ret->labels = map_new()) == NULL) goto ERR;
26 
27  ret->instr = NULL;
28  ret->tokens = NULL;
29  ret->PC = 0;
30  ret->infile[0] = 0;
31  strcpy(ret->outfile, "out.bin");
32  return ret;
33 
34 ERR:
35  FAIL("state_new() failed!\n");
36  state_free(ret);
37  return 0;
38 }
39 
40 
41 int state_load_instr(State* s, char* fname) {
42  s->instr = instruction_load(fname);
43  if (s->instr == NULL) return -1;
44  return 0;
45 }
46 
47 
48 void state_free(State* s) {
49  if (!s) return;
50  map_free(s->defines);
52  map_free(s->labels);
54  free(s);
55 }
56 
61 void print_help(char* pname) {
62  printf("6502 compiler program\nMade by Laszlo Barath in 2020\n\n");
63  printf("Useage:\n> %s [args] <inputfile>\n", pname);
64  printf("(inputfile must be at most %d chars long)\n", STATE_MAX_STRING_LEN - 1);
65  printf("Arguments:\n");
66  printf("\t--output (-o):\tSpecify output file. Expects a file name (max %d chars). Default is 'out.bin'.\n", STATE_MAX_STRING_LEN - 1);
67  printf("\t--define (-d):\tSpecify a constant. Expects a name (max %d chars) and a (decimal) number.\n", MAP_MAX_KEY_LEN - 1);
68  printf("\t--log (-l):\tSet log level. Expects a number in range 1-5. Default is 1.\n");
69  printf("\t--help (-h):\tprints this message. Expects no parameters.\n");
70  printf("\n");
71 }
72 
77  printf("Use the '-h' or --help switches to get more info!\n");
78 }
79 
80 
81 int state_parse_commandline(State* s, int argc, char** argv) {
82  for (int i = 1; i < argc; i++) {
83  if (!strcmp(argv[i], "-o") || !strcmp(argv[i], "--out")) {
84  // Output argument
85  if (i == argc - 1) {
86  ERROR("Argument '%s' excepts parameter(s)!\n", argv[i]);
88  return -1;
89  }
90  char* param = argv[++i];
91  if (strlen(param) > STATE_MAX_STRING_LEN - 1) {
92  ERROR("Out parameter is too long! (max: %d chars)\n", STATE_MAX_STRING_LEN - 1);
93  return -1;
94  }
95  if (param[0] == '-') {
96  ERROR("Output file name can not start with a dash ('-')!\n");
97  return -1;
98  }
99  strncpy(s->outfile, param, STATE_MAX_STRING_LEN);
100  } else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--log")) {
101  // Log argument
102  if (i == argc - 1) {
103  ERROR("Argument '%s' excepts parameter(s)!\n", argv[i]);
105  return -1;
106  }
107  char* param = argv[++i];
108  int level;
109  if (sscanf(param, "%d", &level) != 1) {
110  ERROR("Can not parse log level!\n");
111  return -1;
112  }
113  logging_level(level);
114  } else if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--define")) {
115  // Define argument
116  if (i == argc - 2 || i == argc - 1) {
117  ERROR("Argument '%s' excepts parameter(s)!\n", argv[i]);
119  return -1;
120  }
121  char* name = argv[++i];
122  char* value = argv[++i];
123  int num;
124  if (sscanf(value, "%d", &num) != 1) {
125  ERROR("Can not parse value of define '%s': '%s'!\n", name, value);
126  return -1;
127  }
128  if (strlen(name) > MAP_MAX_KEY_LEN - 1) {
129  ERROR("Define constant name is too long! (max: %d chars)\n", MAP_MAX_KEY_LEN - 1);
130  return -1;
131  }
132  map_set(s->defines, name, num);
133  } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
134  // help
135  print_help(argv[0]);
136  return -1;
137  } else {
138  // rest can only be inputfile
139  if (strlen(argv[i]) > STATE_MAX_STRING_LEN - 1) {
140  ERROR("Input file name is too long! (max: %d chars)\n", STATE_MAX_STRING_LEN - 1);
141  return -1;
142  }
143  if (argv[i][0] == '-') {
144  ERROR("Input file name ('%s') can not start with a dash ('-')!\n", argv[i]);
145  return -1;
146  }
147  strncpy(s->infile, argv[i], STATE_MAX_STRING_LEN);
148  }
149  }
150  if (s->infile[0] == 0) {
151  ERROR("No input file was given!\n");
153  return -1;
154  }
155  return 0;
156 }
157 
158 
State::labels
Map * labels
label locations
Definition: state.h:36
TokensList::tokenslist_free
void tokenslist_free(TokensList *list)
free ALL memory associated with the TokensList object
Definition: tokenslist.c:78
Map::map_set
int map_set(Map *map, char *name, int value)
Sets a key in the map.
Definition: map.c:43
State::infile
char infile[STATE_MAX_STRING_LEN]
input file name
Definition: state.h:44
Instruction::instruction_free
void instruction_free(Instruction *list)
free all memory associated with an Instruction* list
Definition: instructions.c:121
State::instr
Instruction * instr
instruction data
Definition: state.h:40
logging_level
int logging_level(int level)
pseudo-global accessor
Definition: logging.c:6
State::tokens
TokensList * tokens
tokens
Definition: state.h:38
State
Compiler pseudo-global state.
Definition: state.h:32
State::state_load_instr
int state_load_instr(State *s, char *fname)
load instructions from a file
Definition: state.c:41
State::defines
Map * defines
defined constants
Definition: state.h:34
print_short_help
void print_short_help()
print the "use --help" text
Definition: state.c:76
State::state_new
State * state_new()
Create a new State object.
Definition: state.c:16
State::outfile
char outfile[STATE_MAX_STRING_LEN]
output file name
Definition: state.h:46
State::state_free
void state_free(State *s)
free a State object and all associated memory
Definition: state.c:48
Instruction::instruction_load
Instruction * instruction_load(char *fname)
Load instruction data from CSV file.
Definition: instructions.c:18
State::state_parse_commandline
int state_parse_commandline(State *s, int argc, char **argv)
parse command line arguments and update state
Definition: state.c:81
Map::map_free
void map_free(Map *map)
Free the map with all associated memory.
Definition: map.c:62
MapEntry::name
char name[MAP_MAX_KEY_LEN]
key of the entry
Definition: map.h:22
logging.h
logging and fancy-printing
MAP_MAX_KEY_LEN
@ MAP_MAX_KEY_LEN
Key buffer size for Map.
Definition: map.h:14
STATE_MAX_STRING_LEN
@ STATE_MAX_STRING_LEN
max string length for input/output files
Definition: state.h:15
State::PC
int PC
PC (starts at 0)
Definition: state.h:42
state.h
implement State class
print_help
void print_help(char *pname)
print some help on the useage of the program
Definition: state.c:61
FAIL
#define FAIL(...)
Fancy-print a fail (failed step). Works like printf.
Definition: logging.h:45
ERROR
#define ERROR(...)
Fancy-print an error (cause of faliure). Works like printf.
Definition: logging.h:40
Map::map_new
Map * map_new()
Create a new map with 0 elements.
Definition: map.c:17
MapEntry::value
int value
the value the entry holds
Definition: map.h:20