hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit f081dc1a05477851b699c1c2c287f894a6fd1ad5
parent e1c3d8d76fee48f8b55738595d55342900496835
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue, 16 Feb 2021 09:56:53 -0500

all: style improvements

Diffstat:
Mencoding/utf8/decode.ha | 4+---
Mfmt/fmt.ha | 4++--
Mhare/lex/lex.ha | 48++++++++++++++++++++++++++++++++++++++++++------
Mos/+linux/errors.ha | 2+-
Mos/exec/+linux.ha | 5++---
Mos/exec/cmd.ha | 8++++----
Mstrconv/numeric.ha | 12++++++------
Mstrings/iter.ha | 10+++++-----
Mstrings/tokenize.ha | 4+---
9 files changed, 64 insertions(+), 33 deletions(-)

diff --git a/encoding/utf8/decode.ha b/encoding/utf8/decode.ha @@ -63,10 +63,8 @@ export fn next(d: *decoder) (rune | void | more | invalid) = { let decoder = decode(input); for (let i = 0z; i < len(expected); i += 1) { match (next(&decoder)) { + (invalid | more | void ) => abort(), r: rune => assert(r == expected[i]), - invalid => abort(), - more => abort(), - void => abort(), }; }; assert(next(&decoder) is void); diff --git a/fmt/fmt.ha b/fmt/fmt.ha @@ -178,12 +178,12 @@ export fn fprintln( args: formattable... ) (io::error | size) = { let z = match(fprintf(s, fmt, args...)) { - z: size => z, err: io::error => return err, + z: size => z, }; z += match (io::write(s, ['\n': u32: u8])) { - z: size => z, err: io::error => return err, + z: size => z, }; return z; }; diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha @@ -1,5 +1,6 @@ // hare::lex provides a lexer for Hare source code. use ascii; +use encoding::utf8; use io; use strings; @@ -54,9 +55,9 @@ export fn lex(lex: *lexer) ((token, location) | io::EOF | error) = { }, }; - if (ascii::isalpha(r) || r == '_' || r == '@') { + if (is_name(r, false)) { unget(lex, r); - abort(); // TODO: Keywords/names + return lex_name(lex); }; if (ascii::isdigit(r)) { unget(lex, r); @@ -83,6 +84,43 @@ export fn lex(lex: *lexer) ((token, location) | io::EOF | error) = { return (tok, loc); }; +fn is_name(r: rune, num: bool) bool = + ascii::isalpha(r) || r == '_' || r == '@' || (num && ascii::isdigit(r)); + +fn lex_name(lex: *lexer) ((token, location) | io::EOF | error) = { + let chars: []u8 = []; + match (next(lex)) { + r: rune => { + assert(is_name(r, false)); + let enc = utf8::encode_rune(r); + for (let i = 0z; i < len(enc); i += 1) { + append(chars, enc[i]); + }; + }, + (io::EOF | io::error) => abort(), + }; + + for (true) match (next(lex)) { + io::EOF => break, + err: io::error => return err, + r: rune => { + if (!is_name(r, true)) { + unget(lex, r); + break; + }; + let enc = utf8::encode_rune(r); + for (let i = 0z; i < len(enc); i += 1) { + append(chars, enc[i]); + }; + }, + }; + + let name = strings::from_utf8(chars); + io::println(name); + + abort(); +}; + fn lex2( lex: *lexer, loc: location, @@ -300,8 +338,7 @@ fn next(lex: *lexer) (rune | io::EOF | io::error) = { for (true) { return match (io::getrune(lex.in)) { - io::EOF => io::EOF, - err: io::error => err, + e: (io::EOF | io::error) => e, r: rune => { lexloc(lex, r); r; @@ -316,8 +353,7 @@ fn nextw(lex: *lexer) ((rune, location) | io::EOF | io::error) = { for (true) { let loc = mkloc(lex); match (next(lex)) { - err: io::error => return err, - io::EOF => return io::EOF, + e: (io::error | io::EOF) => return e, r: rune => if (!ascii::isspace(r)) { return (r, loc); }, diff --git a/os/+linux/errors.ha b/os/+linux/errors.ha @@ -10,7 +10,7 @@ fn io_errstr(data: *void) str = { fn errno_to_io(err: rt::errno) io::error = { let e = io::os_error { string = &io_errstr, - data = err: uintptr: *void, + data = err: uintptr: *void, }; return e: io::error; }; diff --git a/os/exec/+linux.ha b/os/exec/+linux.ha @@ -13,9 +13,8 @@ export type os_error = struct { // Forks the current process, returning the pid of the child (to the parent) and // void (to the child), or an error. export fn fork() (int | void | error) = match (rt::fork()) { - err: rt::errno => errno_to_os(err), - i: int => i, - void => void, + err: rt::errno => errno_to_os(err), + i: (int | void) => i, }; fn errno_errstr(data: *void) str = { diff --git a/os/exec/cmd.ha b/os/exec/cmd.ha @@ -39,11 +39,11 @@ export fn cmd(name: str, args: str...) (command | error) = { let cmd = command { data: platform = if (strings::contains(name, '/')) match (open(name)) { - p: platform => p, err: os_error => return nocmd, - } else match (lookup(name)) { p: platform => p, + } else match (lookup(name)) { void => return nocmd, + p: platform => p, }, argv = alloc([]str, [], len(args) + 1z), ... @@ -82,13 +82,13 @@ export fn start(cmd: *command) (error | void) = { fn lookup(name: str) (platform | void) = { const path = match (os::getenv("PATH")) { - void => return, + void => return, s: str => s, }; let tok = strings::tokenize(path, ":"); for (true) { const item = match (strings::next_token(&tok)) { - void => break, + void => break, s: str => s, }; let path = strings::concat(item, "/", name); diff --git a/strconv/numeric.ha b/strconv/numeric.ha @@ -23,12 +23,12 @@ export fn signedtos(n: types::signed) const str = signedtosb(n, base::DEC); // [strings::dup] to duplicate the result. export fn unsignedtosb(n: types::unsigned, b: base) const str = { return match (n) { - u: size => ztosb(u, b), - u: uint => utosb(u, b), - u: u8 => u8tosb(u, b), - u: u16 => u16tosb(u, b), - u: u32 => u32tosb(u, b), - u: u64 => u64tosb(u, b), + u: size => ztosb(u, b), + u: uint => utosb(u, b), + u: u8 => u8tosb(u, b), + u: u16 => u16tosb(u, b), + u: u32 => u32tosb(u, b), + u: u64 => u64tosb(u, b), }; }; diff --git a/strings/iter.ha b/strings/iter.ha @@ -22,10 +22,10 @@ export fn next(iter: *iterator) (rune | void) = { void => void, }; return match (utf8::next(&iter.dec)) { - r: rune => r, - void => void, - utf8::more => abort("Invalid UTF-8 string (this should not happen)"), - utf8::invalid => abort("Invalid UTF-8 string (this should not happen)"), + r: rune => r, + void => void, + (utf8::more | utf8::invalid) => + abort("Invalid UTF-8 string (this should not happen)"), }; }; @@ -56,7 +56,7 @@ export fn iter_str(iter: *iterator) str = { for (let i = 0z; i < len(expected2); i += 1) { match (next(&s)) { r: rune => assert(r == expected2[i]), - void => abort(), + void => abort(), }; }; assert(next(&s) is void); diff --git a/strings/tokenize.ha b/strings/tokenize.ha @@ -72,9 +72,7 @@ export fn splitN(in: str, delim: str, n: size) []str = { let tok = tokenize(in, delim); for (let i = 0z; i < n - 1z; i += 1) { match (next_token(&tok)) { - s: str => { - append(toks, s); - }, + s: str => append(toks, s), void => return toks, }; };