NewsBin 0 discussing
--:--:--
Daily Reset
NewsBin
--:--:--
Until Daily Reset
Mainstream Hacker News 17 hours ago

Making a Python interpreter in 1024 bytes

def buzz(): for n in range(101): if n % 15 == 0: print("FizzBuzz") else: if n % 3 == 0: print("Fizz") else: if n % 5 == 0: print("Buzz") else: print(n) buzz() I probably can't fit all of the Python language into an interpreter that is only 1024 bytes of code. So what can I fit that will look like Python? char src[999]; /* Entire program without most spaces. */ int vars[256]; /* Symbol table. */ int pos; /* Next character in src. */ int ch; /* Current character in src. */ int line_start; /* Where the current line starts. */ The expressions are handled like any other recursive descent parser, and they are executed along the way. For example: int parse_sum(void) { int value = parse_term(); while (ch == '+' || ch == '-') { if (ch == '+') value = value + parse_term(); else value = value - parse_term(); } return value; } Straightforward so far. if (ch == 'w' || ch == 'i' || ch == 'f') { int keyword = ch; int loop_var = 0; if (keyword == 'f') { /* "for K in range(N):" */ pos += 2; /* Skip "or". */ loop_var = next(); pos += 8; /* Skip "inrange(". */ vars[loop_var] = 0; } else if (keyword == 'w') pos += 4; /* Skip "hile". */ else pos += 1; /* Skip "f" of "if". */ It also assumes the token boundaries are correct and strips out most whitespace. It keeps indentation and spaces in string literals. if (ch > 96) { value = vars[ch]; next(); } Control flow magic The function for executing blocks of code continues until the indentation decreases. When that happens, it returns, and it is up to the caller to handle the next line. So, it is using the C program's call stack to handle the recursion. void run_block(int min_indent) { for (;;) { int indent = read_indent(); if (ch == '\n') continue; if (indent < min_indent || ch == 0) { pos = line_start; return; } But what about loops?! void skip_to_eol(void) { if (ch != 0 && ch != '\n') { next(); skip_to_eol(); } } I got it down to: Y(){c&&c-10&&Y(G());}. It tests for 0, subtracts 10 to check for a newline, and uses && instead of an if. Then it saves a byte by doing Y(G()); instead of G(); Y();. E(): v[m]<E(); p+=k==102; G(); if(! a){S(j); break;}B(j+1); if(k==105)break; k-102||v[m]++; p=q;}I()-j|c-101? p=u:(p+=4, G(), a? S(j): B(j+1));}else if(c==100){p+=2; k=G(); Y(); v[k]=p; S(j);}else{if(c>96){k=c; while(G()>96); c==40? k-112?(G(), n=p, p=v[k], B(2), p=n, G()):(s[p]-34? printf("%d", E()): Q(), puts(""), G()):(v[k]=E());}Y();}}}main(q, m, h){for(h=m=q=0;~(c=getchar());){c=c-9? c:32; h^=c==34; s[q]=c; q+=c-32?1:!

Original story by Hacker News View original source

0 comments
0 people discussing

Anonymous Discussion

Real voices. Real opinions. No censorship. Resets in 7 hours.

No account needed Anonymous • Resets in 7h

Loading comments...

About NewsBin

Freedom of speech first. Anonymous discussion on today's news. All content resets every 24 hours.

No accounts. No tracking. No censorship. Just honest conversation.