s502 assembler
A very simple assembler for the 6502 line of processors written in C
number.c
Go to the documentation of this file.
1 #include <string.h>
2 
3 #include "number.h"
4 #include "logging.h"
5 
6 
12 int number_char_to_digit(char c) {
13  if ('0' <= c && c <= '9')
14  return c - '0';
15  if ('a' <= c && c <= 'f')
16  c += 'A' - 'a';
17  if ('A' <= c && c <= 'F')
18  return c - 'A' + 10;
19  return NUMBER_ERROR;
20 }
21 
22 
30 int number_parse_number(char* str) {
31  int count = strlen(str);
32 
33  int base = 10;
34  int ptr = 0;
35  int num = 0;
36  if (str[0] == '$') {
37  base = 16;
38  ptr++;
39  }
40  while (ptr < count) {
41  num *= base;
42  int digit = number_char_to_digit(str[ptr]);
43  if (digit == NUMBER_ERROR || digit >= base) {
44  ERROR("Can not interpret number: '%.*s'\n", count, str);
45  return NUMBER_ERROR;
46  }
47 
48  num += digit;
49  ptr++;
50  }
51  return num;
52 }
53 
62 int number_get_raw(State* s, char* str) {
63  if (str[0] == '@' || str[0] == '&') {
64  Map* m = str[0] == '@' ? s->defines : s->labels;
65  int n = map_get(m, &str[1]);
66  if (n < 0) {
67  return str[0] == '@' ? NUMBER_ERROR : NUMBER_LABEL_NODEF;
68  }
69  return n;
70  }
71  // pass error (NUMBER_ERROR value)
72  return number_parse_number(str);
73 }
74 
75 int number_get_number(State* s, char* str) {
76 
77  int p = (str[0] == '>' || str[0] == '<') ? 1 : 0;
78  int num = number_get_raw(s, &str[p]);
79 
80  if (num < 0) return num;
81 
82  num = str[0] == '>' ? num >> 8 : num;
83  num &= str[0] == '>' || str[0] == '<' ? 0xff : 0xffff;
84 
85  return num;
86 }
State::labels
Map * labels
label locations
Definition: state.h:36
number_parse_number
int number_parse_number(char *str)
interpret a string as a decimal or hex number
Definition: number.c:30
State
Compiler pseudo-global state.
Definition: state.h:32
State::defines
Map * defines
defined constants
Definition: state.h:34
Map
Simple key->value map (str->int)
Definition: map.h:34
number_get_raw
int number_get_raw(State *s, char *str)
interpret number without modifiers
Definition: number.c:62
Map::map_get
int map_get(Map *map, char *name)
Get the value of a key.
Definition: map.c:75
logging.h
logging and fancy-printing
number_char_to_digit
int number_char_to_digit(char c)
Convert a hex char to a digit.
Definition: number.c:12
NUMBER_ERROR
@ NUMBER_ERROR
Could not parse a number or constant is undefined.
Definition: number.h:15
number.h
Number module to parse numbers.
number_get_number
int number_get_number(State *s, char *str)
interpret a string as a constant, label or number
Definition: number.c:75
ERROR
#define ERROR(...)
Fancy-print an error (cause of faliure). Works like printf.
Definition: logging.h:40
NUMBER_LABEL_NODEF
@ NUMBER_LABEL_NODEF
Undefined label.
Definition: number.h:17