comparison lwasm/lwasm.c @ 44:1bff302e62a3

Accept negative sign after base prefix
author lost@l-w.ca
date Mon, 04 Apr 2011 18:05:18 -0600
parents 7e92484cfbc3
children ceab04fd2969
comparison
equal deleted inserted replaced
43:18b49cf10ae9 44:1bff302e62a3
276 } 276 }
277 277
278 lw_expr_t lwasm_parse_term(char **p, void *priv) 278 lw_expr_t lwasm_parse_term(char **p, void *priv)
279 { 279 {
280 asmstate_t *as = priv; 280 asmstate_t *as = priv;
281 int neg = 1;
281 int val; 282 int val;
282 283
283 if (!**p) 284 if (!**p)
284 return NULL; 285 return NULL;
285 286
337 if (**p == '&') 338 if (**p == '&')
338 { 339 {
339 // decimal constant 340 // decimal constant
340 int v = 0; 341 int v = 0;
341 (*p)++; 342 (*p)++;
343
344 if (**p == '-')
345 {
346 (*p)++;
347 neg = -1;
348 }
342 349
343 if (!strchr("0123456789", **p)) 350 if (!strchr("0123456789", **p))
344 return NULL; 351 return NULL;
345 352
346 while (**p && strchr("0123456789", **p)) 353 while (**p && strchr("0123456789", **p))
347 { 354 {
348 val = val * 10 + (**p - '0'); 355 val = val * 10 + (**p - '0');
349 (*p)++; 356 (*p)++;
350 } 357 }
351 return lw_expr_build(lw_expr_type_int, v); 358 return lw_expr_build(lw_expr_type_int, v * neg);
352 } 359 }
353 360
354 if (**p == '%') 361 if (**p == '%')
355 { 362 {
356 // binary constant 363 // binary constant
357 int v = 0; 364 int v = 0;
358 (*p)++; 365 (*p)++;
359 366
367 if (**p == '-')
368 {
369 (*p)++;
370 neg = -1;
371 }
372
360 if (**p != '0' && **p != '1') 373 if (**p != '0' && **p != '1')
361 return NULL; 374 return NULL;
362 375
363 while (**p && (**p == '0' || **p == '1')) 376 while (**p && (**p == '0' || **p == '1'))
364 { 377 {
365 val = val * 2 + (**p - '0'); 378 val = val * 2 + (**p - '0');
366 (*p)++; 379 (*p)++;
367 } 380 }
368 return lw_expr_build(lw_expr_type_int, v); 381 return lw_expr_build(lw_expr_type_int, v * neg);
369 } 382 }
370 383
371 if (**p == '$') 384 if (**p == '$')
372 { 385 {
373 // hexadecimal constant 386 // hexadecimal constant
374 int v = 0, v2; 387 int v = 0, v2;
375 (*p)++; 388 (*p)++;
389 if (**p == '-')
390 {
391 (*p)++;
392 neg = -1;
393 }
394
376 if (!strchr("0123456789abcdefABCDEF", **p)) 395 if (!strchr("0123456789abcdefABCDEF", **p))
377 return NULL; 396 return NULL;
378 397
379 while (**p && strchr("0123456789abcdefABCDEF", **p)) 398 while (**p && strchr("0123456789abcdefABCDEF", **p))
380 { 399 {
382 if (v2 > 9) 401 if (v2 > 9)
383 v2 -= 7; 402 v2 -= 7;
384 v = v * 16 + v2; 403 v = v * 16 + v2;
385 (*p)++; 404 (*p)++;
386 } 405 }
387 return lw_expr_build(lw_expr_type_int, v); 406 return lw_expr_build(lw_expr_type_int, v * neg);
388 } 407 }
389 408
390 if (**p == '0' && (*((*p)+1) == 'x' || *((*p)+1) == 'X')) 409 if (**p == '0' && (*((*p)+1) == 'x' || *((*p)+1) == 'X'))
391 { 410 {
392 // hexadecimal constant, C style 411 // hexadecimal constant, C style
410 if (**p == '@' && (*((*p)+1) >= '0' && *((*p)+1) <= '7')) 429 if (**p == '@' && (*((*p)+1) >= '0' && *((*p)+1) <= '7'))
411 { 430 {
412 // octal constant 431 // octal constant
413 int v = 0; 432 int v = 0;
414 (*p)++; 433 (*p)++;
434 if (**p == '-')
435 {
436 (*p)++;
437 neg = -1;
438 }
439
415 440
416 if (!strchr("01234567", **p)) 441 if (!strchr("01234567", **p))
417 return NULL; 442 return NULL;
418 443
419 while (**p && strchr("01234567", **p)) 444 while (**p && strchr("01234567", **p))
420 { 445 {
421 v = v * 8 + (**p - '0'); 446 v = v * 8 + (**p - '0');
422 (*p)++; 447 (*p)++;
423 } 448 }
424 return lw_expr_build(lw_expr_type_int, v); 449 return lw_expr_build(lw_expr_type_int, v * neg);
425 } 450 }
426 451
427 452
428 // symbol or bare decimal or suffix constant here 453 // symbol or bare decimal or suffix constant here
429 do 454 do