shithub: semblance

Download patch

ref: de92a40b756cd06c31c70e77277ca270e8dae4d1
parent: 5dca33a54a4fd738473b429563e840d5c24ce620
author: rodri <rgl@antares-labs.eu>
date: Sun Mar 23 14:33:28 EDT 2025

lexer: support more number formats ([0-9][box][0-9]+)

--- a/lexer.c
+++ b/lexer.c
@@ -14,6 +14,7 @@
 	Token tok;
 	char buf[256], *p;
 	Rune r;
+	int base;
 begin:
 	memset(&tok, 0, sizeof(Token));
 
@@ -58,8 +59,37 @@
 	}
 
 	if(isdigitrune(r)){
-		Bungetrune(l->in);
-		Bgetd(l->in, &tok.v);
+		if(r == '0'){
+			r = Bgetc(l->in);
+			if(r != 'b' && r != 'o' && r != 'x'){
+				Bungetrune(l->in);
+				goto decimal;
+			}
+
+			switch(r){
+			case 'b': base =  2; break;
+			case 'o': base =  8; break;
+			case 'x': base = 16; break;
+			default:  base = 10; break;	/* can't happen but calms the compiler */
+			}
+
+			p = buf;
+			while((r = Bgetrune(l->in)) != Beof && isdigitrune(r)){
+				if(p+runelen(r) >= buf + sizeof(buf)){
+					werrstr("number is too long");
+					return Terr;
+				}
+				p += runetochar(p, &r);
+			}
+			Bungetrune(l->in);
+			*p = 0;
+
+			tok.v = strtoll(buf, nil, base);
+		}else{
+decimal:
+			Bungetrune(l->in);
+			Bgetd(l->in, &tok.v);
+		}
 		tok.type = TNUM;
 	}else if(isalpharune(r) || r == '_'){
 		p = buf;
--