Create a gist now

Instantly share code, notes, and snippets.

cc500.vim
" This is a port of CC500
" http://homepage.ntlworld.com/edmund.grimley-evans/cc500/
"
"-------------------------------------------------------------------------------
" ORIGINAL HEADER
"-------------------------------------------------------------------------------
" Copyright (C) 2006 Edmund GRIMLEY EVANS <edmundo@rano.org>
"
" This program is free software; you can redistribute it and/or modify
" it under the terms of the GNU General Public License as published by
" the Free Software Foundation; either version 2 of the License, or
" (at your option) any later version.
"
" This program is distributed in the hope that it will be useful,
" but WITHOUT ANY WARRANTY; without even the implied warranty of
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" GNU General Public License for more details.
"
" You should have received a copy of the GNU General Public License
" along with this program; if not, write to the Free Software
" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"-------------------------------------------------------------------------------
" A self-compiling compiler for a small subset of C.
" Usage:
" :source cc500.vim
" :call CC500Compile('foo.c', 'a.out')
function! CC500Compile(infile, outfile)
let s:stdin = []
let s:stdout = []
let s:token = ''
let s:nextc = ''
let s:code = []
let s:codepos = 0
let s:code_offset = 0
let s:table = {}
let s:stack_pos = 0
let s:number_of_args = 0
try
let s:stdin = s:readfile(a:infile)
call s:main1()
call s:writefile(s:code, a:outfile)
endtry
endfunction
function! s:lines2bytes(lines)
let bytes = []
let first = 1
for line in a:lines
if !first
call add(bytes, 10)
endif
let first = 0
call extend(bytes, map(range(len(line)), 'line[v:val] == "\n" ? 0 : char2nr(line[v:val])'))
endfor
return bytes
endfunction
function! s:bytes2lines(bytes)
let table = map(range(256), 'printf(''\x%02x'', v:val == 0 ? 10 : v:val)')
let lines = []
let start = 0
while start < len(a:bytes)
let end = index(a:bytes, 10, start)
if end == -1
let end = len(a:bytes)
endif
let line = eval('"' . join(map(range(start, end - 1), 'table[a:bytes[v:val]]'), '') . '"')
call add(lines, line)
if end == len(a:bytes) - 1
call add(lines, '')
endif
let start = end + 1
endwhile
return lines
endfunction
function! s:readfile(filename)
try
let lines = readfile(a:filename, 'b')
catch /^Vim\%((\a\+)\)\=:E484:/
throw "Can't read file"
endtry
let bytes = s:lines2bytes(lines)
return bytes
endfunction
function! s:writefile(bytes, filename)
let lines = s:bytes2lines(a:bytes)
if writefile(lines, a:filename, 'b') != 0
throw "Can't write file"
endif
endfunction
function! s:lshift(a, n)
return a:n == 0 ? a:a : a:n > 31 ? 0 : a:a * s:pow2[a:n]
endfunction
function! s:rshift(a, n)
return a:n == 0 ? a:a : a:n > 31 ? 0 :
\ a:a < 0
\ ? (a:a - 0x80000000) / s:pow2[a:n] + 0x40000000 / s:pow2[a:n - 1]
\ : a:a / s:pow2[a:n]
endfunction
let s:pow2 = [
\ 0x1, 0x2, 0x4, 0x8,
\ 0x10, 0x20, 0x40, 0x80,
\ 0x100, 0x200, 0x400, 0x800,
\ 0x1000, 0x2000, 0x4000, 0x8000,
\ 0x10000, 0x20000, 0x40000, 0x80000,
\ 0x100000, 0x200000, 0x400000, 0x800000,
\ 0x1000000, 0x2000000, 0x4000000, 0x8000000,
\ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
\ ]
let s:EOF = ''
" Our library functions.
"void exit(int);
function! s:exit(int)
throw printf("exit(%d)", a:int)
endfunction
let s:stdin = []
let s:stdout = []
"int getchar(void);
function! s:getchar()
if empty(s:stdin)
return s:EOF
else
return nr2char(remove(s:stdin, 0))
endif
endfunction
"void *malloc(int);
"int putchar(int);
function! s:putchar(c)
call add(s:stdout, a:c)
endfunction
"char *my_realloc(char *old, int oldlen, int newlen)
function! s:my_realloc(old, newlen)
return a:old + repeat([0], a:newlen - len(a:old))
endfunction
"int nextc;
"char *token;
"int token_size;
let s:token = ''
let s:nextc = ''
"void error()
function! s:error()
throw "exit(1)"
endfunction
"int i;
"void takechar()
function! s:takechar()
let s:token .= s:nextc
let s:nextc = s:getchar()
endfunction
"void get_token()
function! s:get_token()
let w = 1
while w
let w = 0
while s:nextc ==# ' ' || s:nextc ==# "\t" || s:nextc ==# "\n"
let s:nextc = s:getchar()
endwhile
let s:token = ''
while ('a' <=# s:nextc && s:nextc <=# 'z') || ('0' <=# s:nextc && s:nextc <=# '9') || s:nextc ==# '_'
call s:takechar()
endwhile
if empty(s:token)
while s:nextc ==# '<' || s:nextc ==# '=' || s:nextc ==# '>' || s:nextc ==# '|' || s:nextc ==# '&' || s:nextc ==# '!'
call s:takechar()
endwhile
endif
if empty(s:token)
if s:nextc ==# "'"
call s:takechar()
while s:nextc !=# "'"
call s:takechar()
endwhile
call s:takechar()
elseif s:nextc ==# '"'
call s:takechar()
while s:nextc !=# '"'
call s:takechar()
endwhile
call s:takechar()
elseif s:nextc ==# '/'
call s:takechar()
if s:nextc ==# '*'
let s:nextc = s:getchar()
while s:nextc !=# '/'
while s:nextc !=# '*'
let s:nextc = s:getchar()
endwhile
let s:nextc = s:getchar()
endwhile
let s:nextc = s:getchar()
let w = 1
endif
elseif s:nextc !=# s:EOF
call s:takechar()
endif
endif
endwhile
endfunction
"int peek(char *s)
function! s:peek(s)
return a:s ==# s:token
endfunction
"int accept(char *s)
function! s:accept(s)
if s:peek(a:s)
call s:get_token()
return 1
else
return 0
endif
endfunction
"void expect(char *s)
function! s:expect(s)
if s:accept(a:s) == 0
call s:error()
endif
endfunction
"char *code;
"int code_size;
"int codepos;
"int code_offset;
let s:code = []
let s:codepos = 0
let s:code_offset = 0
function! s:int32_to_bytes(n)
return [and(a:n, 0xFF), and(s:rshift(a:n, 8), 0xFF), and(s:rshift(a:n, 16), 0xFF), and(s:rshift(a:n, 24), 0xFF)]
endfunction
"void save_int(char *p, int n)
function! s:save_int(p, i, n)
let a:p[a:i + 0] = and(a:n, 0xFF)
let a:p[a:i + 1] = and(s:rshift(a:n, 8), 0xFF)
let a:p[a:i + 2] = and(s:rshift(a:n, 16), 0xFF)
let a:p[a:i + 3] = and(s:rshift(a:n, 24), 0xFF)
endfunction
"int load_int(char *p)
function! s:load_int(p, i)
return and(a:p[a:i + 0], 0xFF) + (and(a:p[a:i + 1], 0xFF) * 0x100) + (and(a:p[a:i + 2], 0xFF) * 0x10000) + (and(a:p[a:i + 3], 0xFF) * 0x1000000)
endfunction
"void emit(int n, char *s)
function! s:emit(s)
call extend(s:code, a:s)
let s:codepos = len(s:code)
endfunction
"void be_push()
function! s:be_push()
call s:emit([0x50]) " push %eax
endfunction
" void be_pop(int n)
function! s:be_pop(n)
call s:emit([0x81, 0xc4] + s:int32_to_bytes(a:n * 4)) " add $(n * 4),%esp
endfunction
"char *table;
"int table_size;
"int table_pos;
"int stack_pos;
let s:table = {}
let s:stack_pos = 0
"int sym_lookup(char *s)
function! s:sym_lookup(s)
return get(s:table, a:s, {})
endfunction
"void sym_declare(char *s, int type, int value)
function! s:sym_declare(s, type, value)
let s:table[a:s] = {'name': a:s, 'type': a:type, 'value': a:value}
endfunction
"int sym_declare_global(char *s)
function! s:sym_declare_global(s)
let current_symbol = s:sym_lookup(a:s)
if empty(current_symbol)
call s:sym_declare(a:s, 'U', s:code_offset)
let current_symbol = s:table[a:s]
endif
return current_symbol
endfunction
"void sym_define_global(int current_symbol)
function! s:sym_define_global(current_symbol)
let v = s:codepos + s:code_offset
if a:current_symbol.type != 'U'
call s:error() " symbol redefined
endif
let i = a:current_symbol.value - s:code_offset
while i
let j = s:load_int(s:code, i) - s:code_offset
call s:save_int(s:code, i, v)
let i = j
endwhile
let a:current_symbol.type = 'D'
let a:current_symbol.value = v
endfunction
"int number_of_args;
let s:number_of_args = 0
"void sym_get_value(char *s)
function! s:sym_get_value(s)
let t = s:sym_lookup(a:s)
if empty(t)
call s:error()
endif
call s:emit([0xb8] + s:int32_to_bytes(t.value))
if t.type == 'D' " defined global
elseif t.type == 'U' " undefined global
let t.value = s:codepos + s:code_offset - 4
elseif t.type == 'L' " local variable
let k = (s:stack_pos - t.value - 1) * 4
call s:emit([0x8d, 0x84, 0x24] + s:int32_to_bytes(k)) " lea (n * 4)(%esp),%eax
elseif t.type == 'A' " argument
let k = (s:stack_pos + s:number_of_args - t.value + 1) * 4
call s:emit([0x8d, 0x84, 0x24] + s:int32_to_bytes(k)) " lea (n * 4)(%esp),%eax
else
call s:error()
endif
endfunction
"void be_start()
function! s:be_start()
call s:emit([0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
call s:emit([0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x54, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00])
call s:emit([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00])
call s:emit([0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x08])
call s:emit([0x00, 0x80, 0x04, 0x08, 0x10, 0x4b, 0x00, 0x00, 0x10, 0x4b, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00])
call s:emit([0x00, 0x10, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x89, 0xc3, 0x31, 0xc0, 0x40, 0xcd, 0x80])
call s:sym_define_global(s:sym_declare_global("exit"))
" pop %ebx ; pop %ebx ; xor %eax,%eax ; inc %eax ; int $0x80
call s:emit([0x5b, 0x5b, 0x31, 0xc0, 0x40, 0xcd, 0x80])
call s:sym_define_global(s:sym_declare_global("getchar"))
" mov $3,%eax ; xor %ebx,%ebx ; push %ebx ; mov %esp,%ecx
call s:emit([0xb8, 0x03, 0x00, 0x00, 0x00, 0x31, 0xdb, 0x53, 0x89, 0xe1])
" xor %edx,%edx ; inc %edx ; int $0x80
" test %eax,%eax ; pop %eax ; jne . + 7
call s:emit([0x31, 0xd2, 0x42, 0xcd, 0x80, 0x85, 0xc0, 0x58, 0x75, 0x05])
" mov $-1,%eax ; ret
call s:emit([0xb8, 0xff, 0xff, 0xff, 0xff, 0xc3])
call s:sym_define_global(s:sym_declare_global("malloc"))
" mov 4(%esp),%eax
call s:emit([0x8b, 0x44, 0x24, 0x04])
" push %eax ; xor %ebx,%ebx ; mov $45,%eax ; int $0x80
call s:emit([0x50, 0x31, 0xdb, 0xb8, 0x2d, 0x00, 0x00, 0x00, 0xcd, 0x80])
" pop %ebx ; add %eax,%ebx ; push %eax ; push %ebx ; mov $45,%eax
call s:emit([0x5b, 0x01, 0xc3, 0x50, 0x53, 0xb8, 0x2d, 0x00, 0x00, 0x00])
" int $0x80 ; pop %ebx ; cmp %eax,%ebx ; pop %eax ; je . + 7
call s:emit([0xcd, 0x80, 0x5b, 0x39, 0xc3, 0x58, 0x74, 0x05])
" mov $-1,%eax ; ret
call s:emit([0xb8, 0xff, 0xff, 0xff, 0xff, 0xc3])
call s:sym_define_global(s:sym_declare_global("putchar"))
" mov $4,%eax ; xor %ebx,%ebx ; inc %ebx
call s:emit([0xb8, 0x04, 0x00, 0x00, 0x00, 0x31, 0xdb, 0x43])
" lea 4(%esp),%ecx ; mov %ebx,%edx ; int $0x80 ; ret
call s:emit([0x8d, 0x4c, 0x24, 0x04, 0x89, 0xda, 0xcd, 0x80, 0xc3])
call s:save_int(s:code, 85, s:codepos - 89) " entry set to first thing in file */
endfunction
"void be_finish()
function! s:be_finish()
call s:save_int(s:code, 68, s:codepos)
call s:save_int(s:code, 72, s:codepos)
let i = 0
while i <= s:codepos - 1
call s:putchar(s:code[i])
let i += 1
endwhile
endfunction
"void promote(int type)
function! s:promote(type)
" 1 = char lval, 2 = int lval, 3 = other
if a:type == 1
call s:emit([0x0f, 0xbe, 0x00]) " movsbl (%eax),%eax
elseif a:type == 2
call s:emit([0x8b, 0x00]) " mov (%eax),%eax
endif
endfunction
"int expression();
" primary-expr:
" identifier
" constant
" ( expression )
"int primary_expr()
function! s:primary_expr()
if '0' <=# s:token[0] && s:token[0] <=# '9'
let n = str2nr(s:token, 10)
call s:emit([0xb8] + s:int32_to_bytes(n)) " mov $x,%eax
let type = 3
elseif 'a' <=# s:token[0] && s:token[0] <=# 'z'
call s:sym_get_value(s:token)
let type = 2
elseif s:accept('(')
let type = s:expression()
if s:peek(')') == 0
call s:error()
endif
elseif len(s:token) == 3 && s:token[0] == "'" && s:token[2] == "'"
call s:emit([0xb8] + s:int32_to_bytes(char2nr(s:token[1]))) " mov $x,%eax
let type = 3
elseif s:token[0] ==# '"'
let b = []
let i = 1
while s:token[i] !=# '"'
if s:token[i] ==# '\' && s:token[i + 1] ==# 'x'
call add(b, str2nr(s:token[i + 2] . s:token[i + 3], 16))
let i += 4
else
call add(b, char2nr(s:token[i]))
let i += 1
endif
endwhile
call add(b, 0x00)
" call ... ; the string ; pop %eax
call s:emit([0xe8] + s:int32_to_bytes(len(b)))
call s:emit(b)
call s:emit([0x58])
let type = 3
else
call s:error()
endif
call s:get_token()
return type
endfunction
"void binary1(int type)
function! s:binary1(type)
call s:promote(a:type)
call s:be_push()
let s:stack_pos += 1
endfunction
"int binary2(int type, int n, char *s)
function! s:binary2(type, b)
call s:promote(a:type)
call s:emit(a:b)
let s:stack_pos -= 1
return 3
endfunction
" postfix-expr:
" primary-expr
" postfix-expr [ expression ]
" postfix-expr ( expression-list-opt )
"int postfix_expr()
function! s:postfix_expr()
let type = s:primary_expr()
if s:accept('[')
call s:binary1(type) " pop %ebx ; add %ebx,%eax
call s:binary2(s:expression(), [0x5b, 0x01, 0xd8])
call s:expect(']')
let type = 1
elseif s:accept('(')
let s = s:stack_pos
call s:be_push()
let s:stack_pos = s:stack_pos + 1
if s:accept(')') == 0
call s:promote(s:expression())
call s:be_push()
let s:stack_pos = s:stack_pos + 1
while s:accept(',')
call s:promote(s:expression())
call s:be_push()
let s:stack_pos = s:stack_pos + 1
endwhile
call s:expect(')')
endif
call s:emit([0x8b, 0x84, 0x24] + s:int32_to_bytes((s:stack_pos - s - 1) * 4)) " mov (n * 4)(%esp),%eax
call s:emit([0xff, 0xd0]) " call *%eax
call s:be_pop(s:stack_pos - s)
let s:stack_pos = s
let type = 3
endif
return type
endfunction
" additive-expr:
" postfix-expr
" additive-expr + postfix-expr
" additive-expr - postfix-expr
"int additive_expr()
function! s:additive_expr()
let type = s:postfix_expr()
while 1
if s:accept('+')
call s:binary1(type) " pop %ebx ; add %ebx,%eax
let type = s:binary2(s:postfix_expr(), [0x5b, 0x01, 0xd8])
elseif s:accept('-')
call s:binary1(type) " pop %ebx ; sub %eax,%ebx ; mov %ebx,%eax
let type = s:binary2(s:postfix_expr(), [0x5b, 0x29, 0xc3, 0x89, 0xd8])
else
return type
endif
endwhile
endfunction
" shift-expr:
" additive-expr
" shift-expr << additive-expr
" shift-expr >> additive-expr
"int shift_expr()
function! s:shift_expr()
let type = s:additive_expr()
while 1
if s:accept('<<')
call s:binary1(type) " mov %eax,%ecx ; pop %eax ; shl %cl,%eax
let type = s:binary2(s:additive_expr(), [0x89, 0xc1, 0x58, 0xd3, 0xe0])
elseif s:accept('>>')
call s:binary1(type) " mov %eax,%ecx ; pop %eax ; sar %cl,%eax
let type = s:binary2(s:additive_expr(), [0x89, 0xc1, 0x58, 0xd3, 0xf8])
else
return type
endif
endwhile
endfunction
" relational-expr:
" shift-expr
" relational-expr <= shift-expr
"int relational_expr()
function! s:relational_expr()
let type = s:shift_expr()
while s:accept('<=')
call s:binary1(type)
" pop %ebx ; cmp %eax,%ebx ; setle %al ; movzbl %al,%eax
let type = s:binary2(s:shift_expr(), [0x5b, 0x39, 0xc3, 0x0f, 0x9e, 0xc0, 0x0f, 0xb6, 0xc0])
endwhile
return type
endfunction
" equality-expr:
" relational-expr
" equality-expr == relational-expr
" equality-expr != relational-expr
"int equality_expr()
function! s:equality_expr()
let type = s:relational_expr()
while 1
if s:accept('==')
call s:binary1(type)
" pop %ebx ; cmp %eax,%ebx ; sete %al ; movzbl %al,%eax
let type = s:binary2(s:relational_expr(), [0x5b, 0x39, 0xc3, 0x0f, 0x94, 0xc0, 0x0f, 0xb6, 0xc0])
elseif s:accept('!=')
call s:binary1(type)
" pop %ebx ; cmp %eax,%ebx ; setne %al ; movzbl %al,%eax
let type = s:binary2(s:relational_expr(), [0x5b, 0x39, 0xc3, 0x0f, 0x95, 0xc0, 0x0f, 0xb6, 0xc0])
else
return type
endif
endwhile
endfunction
" bitwise-and-expr:
" equality-expr
" bitwise-and-expr & equality-expr
"int bitwise_and_expr()
function! s:bitwise_and_expr()
let type = s:equality_expr()
while s:accept('&')
call s:binary1(type) " pop %ebx ; and %ebx,%eax
let type = s:binary2(s:equality_expr(), [0x5b, 0x21, 0xd8])
endwhile
return type
endfunction
" bitwise-or-expr:
" bitwise-and-expr
" bitwise-and-expr | bitwise-or-expr
"int bitwise_or_expr()
function! s:bitwise_or_expr()
let type = s:bitwise_and_expr()
while s:accept('|')
call s:binary1(type) " pop %ebx ; or %ebx,%eax
let type = s:binary2(s:bitwise_and_expr(), [0x5b, 0x09, 0xd8])
endwhile
return type
endfunction
" expression:
" bitwise-or-expr
" bitwise-or-expr = expression
"int expression()
function! s:expression()
let type = s:bitwise_or_expr()
if s:accept('=')
call s:be_push()
let s:stack_pos = s:stack_pos + 1
call s:promote(s:expression())
if type == 2
call s:emit([0x5b, 0x89, 0x03]) " pop %ebx ; mov %eax,(%ebx)
else
call s:emit([0x5b, 0x88, 0x03]) " pop %ebx ; mov %al,(%ebx)
endif
let s:stack_pos = s:stack_pos - 1
let type = 3
endif
return type
endfunction
" type-name:
" char *
" int
"void type_name()
function! s:type_name()
call s:get_token()
while s:accept('*')
endwhile
endfunction
" statement:
" { statement-list-opt }
" type-name identifier ;
" type-name identifier = expression;
" if ( expression ) statement
" if ( expression ) statement else statement
" while ( expression ) statement
" return ;
" expr ;
"void statement()
function! s:statement()
if s:accept('{')
let t = copy(s:table)
let s = s:stack_pos
while s:accept('}') == 0
call s:statement()
endwhile
let s:table = t
call s:be_pop(s:stack_pos - s)
let s:stack_pos = s
elseif s:peek('char') || s:peek('int')
call s:type_name()
call s:sym_declare(s:token, 'L', s:stack_pos)
call s:get_token()
if s:accept('=')
call s:promote(s:expression())
endif
call s:expect(";")
call s:be_push()
let s:stack_pos = s:stack_pos + 1
elseif s:accept('if')
call s:expect("(")
call s:promote(s:expression())
call s:emit([0x85, 0xc0, 0x0f, 0x84, 0, 0, 0, 0]) " test %eax,%eax ; je ...
let p1 = s:codepos
call s:expect(")")
call s:statement()
call s:emit([0xe9, 0, 0, 0, 0]) " jmp ...
let p2 = s:codepos
call s:save_int(s:code, p1 - 4, s:codepos - p1)
if s:accept('else')
call s:statement()
endif
call s:save_int(s:code, p2 - 4, s:codepos - p2)
elseif s:accept('while')
call s:expect("(")
let p1 = s:codepos
call s:promote(s:expression())
call s:emit([0x85, 0xc0, 0x0f, 0x84, 0, 0, 0, 0]) " test %eax,%eax ; je ...
let p2 = s:codepos
call s:expect(")")
call s:statement()
call s:emit([0xe9, 0, 0, 0, 0]) " jmp ...
call s:save_int(s:code, s:codepos - 4, p1 - s:codepos)
call s:save_int(s:code, p2 - 4, s:codepos - p2)
elseif s:accept('return')
if s:peek(';') == 0
call s:promote(s:expression())
endif
call s:expect(";")
call s:be_pop(s:stack_pos)
call s:emit([0xc3]) " ret
else
call s:expression()
call s:expect(";")
endif
endfunction
" program:
" declaration
" declaration program
"
" declaration:
" type-name identifier ;
" type-name identifier ( parameter-list ) ;
" type-name identifier ( parameter-list ) statement
"
" parameter-list:
" parameter-declaration
" parameter-list, parameter-declaration
"
" parameter-declaration:
" type-name identifier-opt
"void program()
function! s:program()
while !empty(s:token)
call s:type_name()
let current_symbol = s:sym_declare_global(s:token)
call s:get_token()
if s:accept(';')
call s:sym_define_global(current_symbol)
call s:emit([0x00, 0x00, 0x00, 0x00])
elseif s:accept('(')
let t = copy(s:table)
let s:number_of_args = 0
while s:accept(')') == 0
let s:number_of_args = s:number_of_args + 1
call s:type_name()
if s:peek(')') == 0
call s:sym_declare(s:token, 'A', s:number_of_args)
call s:get_token()
endif
call s:accept(",") " ignore trailing comma
endwhile
if s:accept(';') == 0
call s:sym_define_global(current_symbol)
call s:statement()
call s:emit([0xc3]) " ret
endif
let s:table = t
else
call s:error()
endif
endwhile
endfunction
"int main1()
function! s:main1()
let s:code_offset = 134512640 " 0x08048000
call s:be_start()
let s:nextc = s:getchar()
call s:get_token()
call s:program()
call s:be_finish()
return 0
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment