New release - version 0.6.1; zasm compiler added - ZeX/OS assembly compiler; lot...
[ZeXOS.git] / apps / zasm / source.c
blobabb356c4a9d323ab23120f35fbc473ce0202221b
1 /*
2 * ZeX/OS
3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <fcntl.h>
23 #include <ctype.h>
24 #include "buffer.h"
25 #include "source.h"
27 var_t var_list;
28 var_t *function_curr;
29 unsigned bin_pos;
32 var_t *var_find (char *name)
34 var_t *var;
36 for (var = var_list.next; var != &var_list; var = var->next) {
37 if (!strcmp (var->name, name))
38 return var;
41 return 0;
44 int var_create (char type, char *name, unsigned len, void *address, unsigned line)
46 var_t *var;
48 /* alloc and init context */
49 var = (var_t *) malloc (sizeof (var_t));
51 if (!var)
52 return 0;
54 var->type = type;
56 var->name = (char *) malloc (sizeof (char) * (len + 1));
58 if (!var->name)
59 return 0;
61 memcpy (var->name, name, len);
62 var->name[len] = '\0';
64 var->address = address;
65 var->line = 0;
67 /* add into list */
68 var->next = &var_list;
69 var->prev = var_list.prev;
70 var->prev->next = var;
71 var->next->prev = var;
73 printf ("var_create () -> '%s' on line %d\n", var->name, line);
75 return 1;
78 int source_nextline (char *source, unsigned size)
80 unsigned i;
82 for (i = 0; i < size; i ++) {
83 //printf ("znak: %c : %d\n", source[i], source[i]);
84 if (source[i] == '\n') {
85 //printf ("source_nextline: %d\n", i);
86 return i;
90 return 0;
93 char *source_param (char *source, unsigned *size)
95 unsigned i;
96 char *param = (char *) 0;
97 unsigned len = *size;
99 for (i = 0; i < len; i ++) {
100 if (!param) {
101 if (source[i] == ' ' || source[i] == '\t') {
102 i ++;
103 continue;
106 if ((source[i] >= 'a' && source[i] <= 'z') ||
107 (source[i] >= 'A' && source[i] <= 'Z') ||
108 (source[i] >= '0' && source[i] <= '9'))
109 param = source + i;
110 } else if (source[i] == ' ' || source[i] == '\t' || source[i] == '\n' || source[i] == ';') {
111 *size = i;
112 return param;
116 return 0;
119 char *source_paramfirst (char *source, unsigned *size)
121 unsigned i;
122 char *param = (char *) 0;
123 unsigned len = *size;
125 for (i = 0; i < len; i ++) {
126 if (!param) {
127 if (source[i] == ' ' || source[i] == '\t')
128 continue;
130 if ((source[i] >= 'a' && source[i] <= 'z') ||
131 (source[i] >= 'A' && source[i] <= 'Z') ||
132 (source[i] >= '0' && source[i] <= '9'))
133 param = source + i;
134 } else if (source[i] == ' ' || source[i] == ',' || source[i] == '\t') {
135 *size = i;
136 return param;
140 return 0;
143 char *source_paramsecond (char *source, unsigned *size)
145 unsigned i;
146 char *param = (char *) 0;
147 unsigned len = *size;
149 for (i = 0; i < len; i ++) {
150 if (!param) {
151 if (source[i] == ' ' || source[i] == '\t' || source[i] == ',')
152 continue;
154 if ((source[i] >= 'a' && source[i] <= 'z') ||
155 (source[i] >= 'A' && source[i] <= 'Z') ||
156 (source[i] >= '0' && source[i] <= '9'))
157 param = source + i;
158 else if (source[i] == '\'')
159 param = source + i;
160 } else if (source[i] == ' ' || source[i] == '\t' || source[i] == '\n' || source[i] == ';') {
161 *size = i-2;
162 return param;
166 return 0;
169 int source_parse (char *source, unsigned size)
171 unsigned i;
172 unsigned line = 1;
174 for (i = 0; i < size; i ++) {
175 /* GLOBAL */
176 if (!strncmp ("global ", source+i, 7)) {
177 unsigned var = size-i-7;
178 char *param = source_param (source+i+7, &var);
180 if (!param) {
181 printf ("ERROR -> !param\n");
182 return 0;
185 var_create (VAR_TYPE_GLOBAL, param, var, (void *) 0x0 + i, line);
187 i += source_nextline (source+i, size-i);
189 line ++;
190 continue;
193 /* MOV */
194 if (!strncmp ("mov ", source+i, 4)) {
195 unsigned reg_len = size-i-4;
196 char *paramreg = source_paramfirst (source+i+4, &reg_len);
198 if (!paramreg) {
199 printf ("ERROR -> !paramreg\n");
200 return 0;
203 unsigned val_len = size-reg_len-i-4;
204 char *paramval = source_paramsecond (source+i+reg_len+4, &val_len);
206 if (!paramval) {
207 printf ("ERROR -> !val_len\n");
208 return 0;
211 i += source_nextline (source+i, size-i);
213 paramreg[reg_len] = '\0';
214 paramval[val_len] = '\0';
216 printf ("mov: %s, %s\n", paramreg, paramval);
218 unsigned char reg = 0;
220 if (paramreg[0] == 'e' && paramreg[1] == 'a' && paramreg[2] == 'x')
221 reg = 0xb8; // eax
222 else if (paramreg[0] == 'e' && paramreg[1] == 'b' && paramreg[2] == 'x')
223 reg = 0xbb; // ebx
224 else if (paramreg[0] == 'e' && paramreg[1] == 'c' && paramreg[2] == 'x')
225 reg = 0xb9; // ecx
226 else if (paramreg[0] == 'e' && paramreg[1] == 'd' && paramreg[2] == 'x')
227 reg = 0xba; // edx
229 buffer_copy (bin_pos, (void *) &reg, 1);
230 bin_pos ++;
232 /* Let's convert parameter to binary number */
233 if (paramval[0] == '\'') {
234 if (val_len < 3) {
235 printf ("ERROR -> wrong parameter syntax - %d != 3, line: %d\n", val_len, line);
236 return 0;
239 if (paramval[2] != '\'' || paramval[1] == '\'') {
240 printf ("ERROR -> wrong parameter syntax, line: %d\n", line);
241 return 0;
244 int c = paramval[1];
245 //printf ("mov val char = %c\n", c);
247 buffer_copy (bin_pos, (void *) &c, sizeof (int));
248 bin_pos += sizeof (int);
250 } else if (paramval[0] == '0' && paramval[1] == 'x') {
251 char *endptr, *str = paramval+2;
253 long val = strtol (str, &endptr, 16);
255 //printf ("mov val hexa = %d\n", val);
257 buffer_copy (bin_pos, (void *) &val, sizeof (int));
258 bin_pos += sizeof (int);
259 } else {
260 unsigned x;
261 for (x = 0; x < val_len-1; x ++) {
262 if (!(paramval[x] >= '0' && paramval[x] <= '9')) {
263 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line);
264 return 0;
268 int num = atoi (paramval);
270 //printf ("mov val digit = %d\n", num);
272 buffer_copy (bin_pos, (void *) &num, sizeof (int));
273 bin_pos += sizeof (int);
276 line ++;
277 continue;
280 /* INT */
281 if (!strncmp ("int ", source+i, 4)) {
282 unsigned var = size-i-4;
283 char *param = source_param (source+i+4, &var);
285 if (!param) {
286 printf ("ERROR -> !param\n");
287 return 0;
290 i += source_nextline (source+i, size-i);
292 unsigned char intr = 0xcd; // int
293 buffer_copy (bin_pos, (void *) &intr, 1);
294 bin_pos ++;
296 param[var] = '\0';
298 if (param[0] == '0' && param[1] == 'x') {
299 char *endptr, *str = param+2;
301 long val = strtol (str, &endptr, 16);
303 //printf ("int: 0x%x\n", val);
305 buffer_copy (bin_pos, (void *) &val, 1);
306 bin_pos ++;
307 } else {
308 unsigned x;
309 for (x = 0; x < var; x ++) {
310 if (!isdigit (param[x])) {
311 printf ("ERROR -> wrong parameter syntax - only numbers are allowed, line: %d\n", line);
312 return 0;
316 int num = atoi (param);
318 buffer_copy (bin_pos, (void *) &num, 1);
319 bin_pos ++;
322 printf ("int: %s\n", param);
324 line ++;
325 continue;
328 /* RET */
329 if (!strncmp ("ret", source+i, 3)) {
330 if (!function_curr) {
331 printf ("ERROR -> ret cannot be called out of function, line: %d\n", line);
332 return 0;
335 printf ("Function %s end on line %d\n", function_curr->name, line);
337 function_curr = 0;
339 unsigned char ret = 0xc3;
340 buffer_copy (bin_pos, (void *) &ret, 1);
341 bin_pos ++;
343 i += source_nextline (source+i, size-i);
345 line ++;
346 continue;
349 if ((source[i] >= 'a' && source[i] <= 'z') || (source[i] >= 'A' && source[i] <= 'Z')) {
350 unsigned y;
352 for (y = i; y < size-i; y ++) {
353 /* Function */
354 if (source[y] == ':') {
355 source[y] = '\0';
357 var_t *var = var_find (source+i);
359 if (!var) {
360 printf ("ERROR -> unknown variable '%s', line %d\n", source+i, line);
361 return 0;
364 printf ("Function '%s' on line %d\n", var->name, line);
366 function_curr = var; // set current function
367 break;
371 if (source[y] == ' ' || source[y] == '\t' || source[y] == '\n' || source[y] == 32 || source[y] == ';') {
372 source[y] = '\0';
374 printf ("ERROR -> unknown command '%s', line: %d - %d, %c\n", source+i, line, i, source[i]);
375 return 0;
379 i = y;
380 } else {
381 //if (source[i] != ' ' || source[i] != ';')
382 //printf ("ERROR -> unspecified character '%c', line: %d\n", source[i], line);
383 if (source[i] == ';') {
384 i += source_nextline (source+i, size-i);
385 line ++;
386 continue;
390 if (source[i] == '\n')
391 line ++;
394 return 1;
397 char *source_open (char *file)
399 int fd = open (file, O_RDONLY);
401 if (!fd) {
402 printf ("error -> file '%s' not found !\n", file);
403 return 0;
406 char *buffer = (char *) malloc (sizeof (char) * 513);
408 if (!buffer) {
409 printf ("ERROR -> out of memory !\n");
410 return 0;
413 if (!read (fd, buffer, 512)) {
414 printf ("ERROR -> !source_open ()\n");
415 return 0;
418 printf ("Source: %s\n", buffer);
420 return buffer;
423 int source_init ()
425 var_list.next = &var_list;
426 var_list.prev = &var_list;
428 bin_pos = 0x1000;
430 function_curr = 0;
432 return 1;