parse negative constants
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
func rule110_step[state: Array] : Array
|
func rule110_step[state: Array] : void
|
||||||
new_state := []
|
new_state := []
|
||||||
|
|
||||||
for i in 0..state->size
|
for i in 0..state->size
|
||||||
@@ -12,7 +12,8 @@ func rule110_step[state: Array] : Array
|
|||||||
|
|
||||||
array.push(new_state, !((!left && !center && !right) || (left && !center && !right) || (left && center && right)))
|
array.push(new_state, !((!left && !center && !right) || (left && !center && !right) || (left && center && right)))
|
||||||
|
|
||||||
return new_state
|
mem.copy(new_state->data, state->data, state->size * 8)
|
||||||
|
array.free(new_state)
|
||||||
|
|
||||||
func print_state[state: Array]: void
|
func print_state[state: Array]: void
|
||||||
for i in 0..state->size
|
for i in 0..state->size
|
||||||
@@ -32,7 +33,7 @@ func main[] : i64
|
|||||||
|
|
||||||
print_state(state)
|
print_state(state)
|
||||||
for i in 0..SIZE
|
for i in 0..SIZE
|
||||||
state = rule110_step(state)
|
rule110_step(state)
|
||||||
print_state(state)
|
print_state(state)
|
||||||
|
|
||||||
array.free(state)
|
array.free(state)
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ _builtin_environ:
|
|||||||
emit!(&mut self.output, " mov QWORD [rbp-{}], {}", offset, reg);
|
emit!(&mut self.output, " mov QWORD [rbp-{}], {}", offset, reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Stmt::Const { name: _, value: _ } => {
|
Stmt::Const { .. } => {
|
||||||
// handled in SymbolTable
|
// handled in SymbolTable
|
||||||
}
|
}
|
||||||
Stmt::Block(statements) => {
|
Stmt::Block(statements) => {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ pub enum Stmt {
|
|||||||
Const {
|
Const {
|
||||||
name: Token,
|
name: Token,
|
||||||
value: Token,
|
value: Token,
|
||||||
|
neg: bool,
|
||||||
},
|
},
|
||||||
Block(Vec<Stmt>),
|
Block(Vec<Stmt>),
|
||||||
If {
|
If {
|
||||||
@@ -271,8 +272,9 @@ impl Parser {
|
|||||||
fn const_declaration(&mut self) -> Result<Stmt, ZernError> {
|
fn const_declaration(&mut self) -> Result<Stmt, ZernError> {
|
||||||
let name = self.consume(TokenType::Identifier, "expected const name")?;
|
let name = self.consume(TokenType::Identifier, "expected const name")?;
|
||||||
self.consume(TokenType::Equal, "expected '=' after const name")?;
|
self.consume(TokenType::Equal, "expected '=' after const name")?;
|
||||||
|
let neg = self.match_token(&[TokenType::Minus]);
|
||||||
let value = self.consume(TokenType::IntLiteral, "expected a number after '='")?;
|
let value = self.consume(TokenType::IntLiteral, "expected a number after '='")?;
|
||||||
Ok(Stmt::Const { name, value })
|
Ok(Stmt::Const { name, value, neg })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extern_declaration(&mut self) -> Result<Stmt, ZernError> {
|
fn extern_declaration(&mut self) -> Result<Stmt, ZernError> {
|
||||||
|
|||||||
@@ -1,16 +1,29 @@
|
|||||||
|
const STDIN = 0
|
||||||
|
const STDOUT = 1
|
||||||
|
|
||||||
|
const SIGABRT = 6
|
||||||
|
|
||||||
|
const AT_FDCWD = -100
|
||||||
|
|
||||||
const S_IFDIR = 0o040000
|
const S_IFDIR = 0o040000
|
||||||
const S_IFMT = 0o170000
|
const S_IFMT = 0o170000
|
||||||
|
|
||||||
const PROT_READ = 1
|
const PROT_READ = 1
|
||||||
const PROT_WRITE = 2
|
const PROT_WRITE = 2
|
||||||
|
|
||||||
const MAP_PRIVATE = 2
|
const MAP_PRIVATE = 2
|
||||||
const MAP_ANONYMOUS = 32
|
const MAP_ANONYMOUS = 32
|
||||||
|
|
||||||
const O_RDONLY = 0
|
const O_RDONLY = 0
|
||||||
const O_WRONLY = 1
|
const O_WRONLY = 1
|
||||||
const O_CREAT = 64
|
const O_CREAT = 64
|
||||||
const O_TRUNC = 512
|
const O_TRUNC = 512
|
||||||
|
|
||||||
const SEEK_SET = 0
|
const SEEK_SET = 0
|
||||||
const SEEK_END = 2
|
const SEEK_END = 2
|
||||||
|
|
||||||
|
const F_OK = 0
|
||||||
|
|
||||||
const SYS_read = 0
|
const SYS_read = 0
|
||||||
const SYS_write = 1
|
const SYS_write = 1
|
||||||
const SYS_open = 2
|
const SYS_open = 2
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ const SOCK_STREAM = 1
|
|||||||
const SOCK_DGRAM = 2
|
const SOCK_DGRAM = 2
|
||||||
const SOL_SOCKET = 1
|
const SOL_SOCKET = 1
|
||||||
const SO_REUSEADDR = 2
|
const SO_REUSEADDR = 2
|
||||||
|
const SOMAXCONN = 128
|
||||||
|
|
||||||
const DNS_TYPE_A = 1
|
const DNS_TYPE_A = 1
|
||||||
const DNS_CLASS_IN = 1
|
const DNS_CLASS_IN = 1
|
||||||
@@ -25,7 +26,7 @@ func net.listen[packed_host: i64, port: i64] : i64, bool
|
|||||||
_builtin_syscall(SYS_close, s)
|
_builtin_syscall(SYS_close, s)
|
||||||
return -1, false
|
return -1, false
|
||||||
|
|
||||||
if _builtin_syscall(SYS_listen, s, 128) < 0
|
if _builtin_syscall(SYS_listen, s, SOMAXCONN) < 0
|
||||||
_builtin_syscall(SYS_close, s)
|
_builtin_syscall(SYS_close, s)
|
||||||
return -1, false
|
return -1, false
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ func panic[msg: str] : void
|
|||||||
io.print("PANIC: ")
|
io.print("PANIC: ")
|
||||||
io.println(msg)
|
io.println(msg)
|
||||||
// for gdb backtrace
|
// for gdb backtrace
|
||||||
_builtin_syscall(SYS_kill, os.getpid(), 6)
|
_builtin_syscall(SYS_kill, os.getpid(), SIGABRT)
|
||||||
os.exit(1)
|
os.exit(1)
|
||||||
|
|
||||||
const MEM_BLOCK_SIZE = 32
|
const MEM_BLOCK_SIZE = 32
|
||||||
@@ -332,7 +332,7 @@ func io.snprintf[..] : i64
|
|||||||
return n
|
return n
|
||||||
|
|
||||||
func io.print_sized[x: ptr, size: i64] : void
|
func io.print_sized[x: ptr, size: i64] : void
|
||||||
_builtin_syscall(SYS_write, 1, x, size)
|
_builtin_syscall(SYS_write, STDOUT, x, size)
|
||||||
|
|
||||||
func io.print[x: str] : void
|
func io.print[x: str] : void
|
||||||
io.print_sized(x as ptr, str.len(x))
|
io.print_sized(x as ptr, str.len(x))
|
||||||
@@ -367,7 +367,7 @@ func io.println_i64[x: i64] : void
|
|||||||
|
|
||||||
func io.read_char[] : u8
|
func io.read_char[] : u8
|
||||||
c := 0 as u8
|
c := 0 as u8
|
||||||
_builtin_syscall(SYS_read, 0, ^c, 1)
|
_builtin_syscall(SYS_read, STDIN, ^c, 1)
|
||||||
return c
|
return c
|
||||||
|
|
||||||
func io.read_line[] : str
|
func io.read_line[] : str
|
||||||
@@ -382,19 +382,19 @@ func io.read_line[] : str
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
func io.file_exists[path: str] : bool
|
func io.file_exists[path: str] : bool
|
||||||
return _builtin_syscall(SYS_faccessat, -100, path, 0, 0) == 0
|
return _builtin_syscall(SYS_faccessat, AT_FDCWD, path, F_OK, 0) == 0
|
||||||
|
|
||||||
func io.is_a_directory[path: str] : bool
|
func io.is_a_directory[path: str] : bool
|
||||||
st := _stackalloc(256) // it has 21 mixed-size fields so ptr for now
|
st := _stackalloc(256) // it has 21 mixed-size fields so ptr for now
|
||||||
|
|
||||||
rc := _builtin_syscall(SYS_newfstatat, -100, path, st, 0)
|
rc := _builtin_syscall(SYS_newfstatat, AT_FDCWD, path, st, 0)
|
||||||
if rc != 0
|
if rc != 0
|
||||||
return false
|
return false
|
||||||
|
|
||||||
return (mem.read32(st + 24) & S_IFMT) == S_IFDIR
|
return (mem.read32(st + 24) & S_IFMT) == S_IFDIR
|
||||||
|
|
||||||
func io.read_text_file[path: str] : str, bool
|
func io.read_text_file[path: str] : str, bool
|
||||||
fd := _builtin_syscall(SYS_openat, -100, path, O_RDONLY, 0)
|
fd := _builtin_syscall(SYS_openat, AT_FDCWD, path, O_RDONLY, 0)
|
||||||
if fd < 0
|
if fd < 0
|
||||||
return 0 as str, false
|
return 0 as str, false
|
||||||
|
|
||||||
@@ -413,13 +413,13 @@ func io.read_text_file[path: str] : str, bool
|
|||||||
return buffer as str, true
|
return buffer as str, true
|
||||||
|
|
||||||
func io.read_binary_file[path: str] : Blob, bool
|
func io.read_binary_file[path: str] : Blob, bool
|
||||||
fd := _builtin_syscall(SYS_openat, -100, path, 0, 0)
|
fd := _builtin_syscall(SYS_openat, AT_FDCWD, path, O_RDONLY, 0)
|
||||||
if fd < 0
|
if fd < 0
|
||||||
return 0 as Blob, false
|
return 0 as Blob, false
|
||||||
|
|
||||||
buf := new* Blob
|
buf := new* Blob
|
||||||
buf->size = _builtin_syscall(SYS_lseek, fd, 0, 2)
|
buf->size = _builtin_syscall(SYS_lseek, fd, 0, SEEK_END)
|
||||||
_builtin_syscall(SYS_lseek, fd, 0, 0)
|
_builtin_syscall(SYS_lseek, fd, 0, SEEK_SET)
|
||||||
|
|
||||||
buf->data = mem.alloc(buf->size)
|
buf->data = mem.alloc(buf->size)
|
||||||
|
|
||||||
@@ -436,7 +436,7 @@ func io.write_file[path: str, content: str] : bool
|
|||||||
return io.write_binary_file(path, content as ptr, str.len(content))
|
return io.write_binary_file(path, content as ptr, str.len(content))
|
||||||
|
|
||||||
func io.write_binary_file[path: str, content: ptr, size: i64] : bool
|
func io.write_binary_file[path: str, content: ptr, size: i64] : bool
|
||||||
fd := _builtin_syscall(SYS_openat, -100, path, O_WRONLY|O_CREAT|O_TRUNC, 0o644)
|
fd := _builtin_syscall(SYS_openat, AT_FDCWD, path, O_WRONLY|O_CREAT|O_TRUNC, 0o644)
|
||||||
if fd < 0
|
if fd < 0
|
||||||
return false
|
return false
|
||||||
|
|
||||||
@@ -863,6 +863,13 @@ func array.free[xs: Array] : void
|
|||||||
mem.free(xs->data)
|
mem.free(xs->data)
|
||||||
mem.free(xs)
|
mem.free(xs)
|
||||||
|
|
||||||
|
func array.free_with_items[xs: Array] : void
|
||||||
|
if xs->data != 0
|
||||||
|
for i in 0..xs->size
|
||||||
|
mem.free(array.nth(xs, i))
|
||||||
|
mem.free(xs->data)
|
||||||
|
mem.free(xs)
|
||||||
|
|
||||||
func array.pop[xs: Array] : any
|
func array.pop[xs: Array] : any
|
||||||
if xs->size == 0
|
if xs->size == 0
|
||||||
panic("array.pop on empty array")
|
panic("array.pop on empty array")
|
||||||
@@ -1082,7 +1089,7 @@ func os.run_shell_command[command: str] : i64, bool
|
|||||||
return -(st & 0x7f), true
|
return -(st & 0x7f), true
|
||||||
|
|
||||||
func os.list_directory[path: str] : Array, bool
|
func os.list_directory[path: str] : Array, bool
|
||||||
fd := _builtin_syscall(SYS_openat, -100, path, O_RDONLY, 0)
|
fd := _builtin_syscall(SYS_openat, AT_FDCWD, path, O_RDONLY, 0)
|
||||||
if fd < 0
|
if fd < 0
|
||||||
return 0 as Array, false
|
return 0 as Array, false
|
||||||
|
|
||||||
@@ -1091,10 +1098,7 @@ func os.list_directory[path: str] : Array, bool
|
|||||||
while true
|
while true
|
||||||
n := _builtin_syscall(SYS_getdents64, fd, buf, 1024)
|
n := _builtin_syscall(SYS_getdents64, fd, buf, 1024)
|
||||||
if n < 0
|
if n < 0
|
||||||
for i in 0..files->size
|
array.free_with_items(files)
|
||||||
mem.free(array.nth(files, i))
|
|
||||||
array.free(files)
|
|
||||||
|
|
||||||
_builtin_syscall(SYS_close, fd)
|
_builtin_syscall(SYS_close, fd)
|
||||||
return 0 as Array, false
|
return 0 as Array, false
|
||||||
else if n == 0
|
else if n == 0
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ impl FnType {
|
|||||||
|
|
||||||
pub struct SymbolTable {
|
pub struct SymbolTable {
|
||||||
pub functions: HashMap<String, FnType>,
|
pub functions: HashMap<String, FnType>,
|
||||||
pub constants: HashMap<String, u64>,
|
pub constants: HashMap<String, i64>,
|
||||||
pub structs: HashMap<String, HashMap<String, StructField>>,
|
pub structs: HashMap<String, HashMap<String, StructField>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,24 +63,21 @@ impl SymbolTable {
|
|||||||
|
|
||||||
pub fn register_declaration(&mut self, stmt: &Stmt) -> Result<(), ZernError> {
|
pub fn register_declaration(&mut self, stmt: &Stmt) -> Result<(), ZernError> {
|
||||||
match stmt {
|
match stmt {
|
||||||
Stmt::Const { name, value } => {
|
Stmt::Const { name, value, neg } => {
|
||||||
if self.is_name_defined(&name.lexeme) {
|
if self.is_name_defined(&name.lexeme) {
|
||||||
return error!(name.loc, format!("tried to redefine '{}'", name.lexeme));
|
return error!(name.loc, format!("tried to redefine '{}'", name.lexeme));
|
||||||
}
|
}
|
||||||
if value.lexeme.starts_with("0x") {
|
let mut value = if value.lexeme.starts_with("0x") {
|
||||||
self.constants.insert(
|
u64::from_str_radix(&value.lexeme[2..], 16).unwrap()
|
||||||
name.lexeme.clone(),
|
|
||||||
u64::from_str_radix(&value.lexeme[2..], 16).unwrap(),
|
|
||||||
);
|
|
||||||
} else if value.lexeme.starts_with("0o") {
|
} else if value.lexeme.starts_with("0o") {
|
||||||
self.constants.insert(
|
u64::from_str_radix(&value.lexeme[2..], 8).unwrap()
|
||||||
name.lexeme.clone(),
|
|
||||||
u64::from_str_radix(&value.lexeme[2..], 8).unwrap(),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
self.constants
|
value.lexeme.parse().unwrap()
|
||||||
.insert(name.lexeme.clone(), value.lexeme.parse().unwrap());
|
} as i64;
|
||||||
|
if *neg {
|
||||||
|
value = -value;
|
||||||
}
|
}
|
||||||
|
self.constants.insert(name.lexeme.clone(), value);
|
||||||
}
|
}
|
||||||
Stmt::Extern(name) => {
|
Stmt::Extern(name) => {
|
||||||
if self.is_name_defined(&name.lexeme) {
|
if self.is_name_defined(&name.lexeme) {
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ impl<'a> TypeChecker<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Stmt::Const { name: _, value: _ } => {
|
Stmt::Const { .. } => {
|
||||||
// handled in SymbolTable
|
// handled in SymbolTable
|
||||||
}
|
}
|
||||||
Stmt::Block(stmts) => {
|
Stmt::Block(stmts) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user