mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Fix core library for the new procedure parameter addressing mode
This commit is contained in:
@@ -19,6 +19,6 @@ unload_library :: proc(library: Library) -> bool {
|
|||||||
symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) {
|
symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) {
|
||||||
c_str := strings.clone_to_cstring(symbol, context.temp_allocator);
|
c_str := strings.clone_to_cstring(symbol, context.temp_allocator);
|
||||||
ptr = win32.get_proc_address(cast(win32.Hmodule)library, c_str);
|
ptr = win32.get_proc_address(cast(win32.Hmodule)library, c_str);
|
||||||
found == ptr != nil;
|
found = ptr != nil;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-10
@@ -190,7 +190,7 @@ next_token :: proc(p: ^Parser) -> Token {
|
|||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
unquote_char :: proc(s: string, quote: byte) -> (r: rune, multiple_bytes: bool, tail_string: string, success: bool) {
|
unquote_char :: proc(str: string, quote: byte) -> (r: rune, multiple_bytes: bool, tail_string: string, success: bool) {
|
||||||
hex_to_int :: proc(c: byte) -> int {
|
hex_to_int :: proc(c: byte) -> int {
|
||||||
switch c {
|
switch c {
|
||||||
case '0'..'9': return int(c-'0');
|
case '0'..'9': return int(c-'0');
|
||||||
@@ -201,18 +201,19 @@ unquote_char :: proc(s: string, quote: byte) -> (r: rune, multiple_bytes: bool,
|
|||||||
}
|
}
|
||||||
w: int;
|
w: int;
|
||||||
|
|
||||||
if s[0] == quote && quote == '"' {
|
if str[0] == quote && quote == '"' {
|
||||||
return;
|
return;
|
||||||
} else if s[0] >= 0x80 {
|
} else if str[0] >= 0x80 {
|
||||||
r, w = utf8.decode_rune_in_string(s);
|
r, w = utf8.decode_rune_in_string(str);
|
||||||
return r, true, s[w:], true;
|
return r, true, str[w:], true;
|
||||||
} else if s[0] != '\\' {
|
} else if str[0] != '\\' {
|
||||||
return rune(s[0]), false, s[1:], true;
|
return rune(str[0]), false, str[1:], true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(s) <= 1 {
|
if len(str) <= 1 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
s := str;
|
||||||
c := s[1];
|
c := s[1];
|
||||||
s = s[2:];
|
s = s[2:];
|
||||||
|
|
||||||
@@ -502,7 +503,7 @@ parse_operand :: proc(p: ^Parser) -> (Value, Pos) {
|
|||||||
|
|
||||||
parse_atom_expr :: proc(p: ^Parser, operand: Value, pos: Pos) -> (Value, Pos) {
|
parse_atom_expr :: proc(p: ^Parser, operand: Value, pos: Pos) -> (Value, Pos) {
|
||||||
loop := true;
|
loop := true;
|
||||||
for loop {
|
for operand := operand; loop; {
|
||||||
switch p.curr_token.kind {
|
switch p.curr_token.kind {
|
||||||
case Kind.Period:
|
case Kind.Period:
|
||||||
next_token(p);
|
next_token(p);
|
||||||
@@ -664,8 +665,9 @@ match_values :: proc(left, right: ^Value) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
calculate_binary_value :: proc(p: ^Parser, op: Kind, x, y: Value) -> (Value, bool) {
|
calculate_binary_value :: proc(p: ^Parser, op: Kind, a, b: Value) -> (Value, bool) {
|
||||||
// TODO(bill): Calculate value as you go!
|
// TODO(bill): Calculate value as you go!
|
||||||
|
x, y := a, b;
|
||||||
match_values(&x, &y);
|
match_values(&x, &y);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -286,9 +286,10 @@ scan_number :: proc(t: ^Tokenizer, seen_decimal_point: bool) -> (Kind, string) {
|
|||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scan_exponent :: proc(t: ^Tokenizer, tok: Kind, offset: int) -> (Kind, string) {
|
scan_exponent :: proc(t: ^Tokenizer, tok: Kind, offset: int) -> (kind: Kind, text: string) {
|
||||||
|
kind = tok;
|
||||||
if t.curr_rune == 'e' || t.curr_rune == 'E' {
|
if t.curr_rune == 'e' || t.curr_rune == 'E' {
|
||||||
tok = Float;
|
kind = Float;
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
if t.curr_rune == '-' || t.curr_rune == '+' {
|
if t.curr_rune == '-' || t.curr_rune == '+' {
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
@@ -299,16 +300,18 @@ scan_number :: proc(t: ^Tokenizer, seen_decimal_point: bool) -> (Kind, string) {
|
|||||||
token_error(t, "Illegal floating point exponent");
|
token_error(t, "Illegal floating point exponent");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tok, string(t.src[offset : t.offset]);
|
text = string(t.src[offset : t.offset]);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
scan_fraction :: proc(t: ^Tokenizer, tok: Kind, offset: int) -> (Kind, string) {
|
scan_fraction :: proc(t: ^Tokenizer, tok: Kind, offset: int) -> (kind: Kind, text: string) {
|
||||||
|
kind = tok;
|
||||||
if t.curr_rune == '.' {
|
if t.curr_rune == '.' {
|
||||||
tok = Float;
|
kind = Float;
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
scan_mantissa(t, 10);
|
scan_mantissa(t, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
return scan_exponent(t, tok, offset);
|
return scan_exponent(t, kind, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
offset := t.offset;
|
offset := t.offset;
|
||||||
|
|||||||
@@ -281,8 +281,8 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error {
|
|||||||
if ti == nil {
|
if ti == nil {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ti = runtime.type_info_base(ti);
|
t := runtime.type_info_base(ti);
|
||||||
switch info in ti.variant {
|
switch info in t.variant {
|
||||||
case runtime.Type_Info_Integer:
|
case runtime.Type_Info_Integer:
|
||||||
using runtime.Type_Info_Endianness;
|
using runtime.Type_Info_Endianness;
|
||||||
switch info.endianness {
|
switch info.endianness {
|
||||||
|
|||||||
@@ -333,7 +333,8 @@ get_token :: proc(t: ^Tokenizer) -> (token: Token, err: Error) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
is_valid_number :: proc(s: string, spec: Specification) -> bool {
|
is_valid_number :: proc(str: string, spec: Specification) -> bool {
|
||||||
|
s := str;
|
||||||
if s == "" {
|
if s == "" {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -395,7 +396,8 @@ is_valid_number :: proc(s: string, spec: Specification) -> bool {
|
|||||||
return s == "";
|
return s == "";
|
||||||
}
|
}
|
||||||
|
|
||||||
is_valid_string_literal :: proc(s: string, spec: Specification) -> bool {
|
is_valid_string_literal :: proc(str: string, spec: Specification) -> bool {
|
||||||
|
s := str;
|
||||||
if len(s) < 2 {
|
if len(s) < 2 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-20
@@ -152,23 +152,21 @@ remainder_f32 :: proc(x, y: f32) -> f32 { return x - round(x/y) * y; }
|
|||||||
remainder_f64 :: proc(x, y: f64) -> f64 { return x - round(x/y) * y; }
|
remainder_f64 :: proc(x, y: f64) -> f64 { return x - round(x/y) * y; }
|
||||||
remainder :: proc{remainder_f32, remainder_f64};
|
remainder :: proc{remainder_f32, remainder_f64};
|
||||||
|
|
||||||
mod_f32 :: proc(x, y: f32) -> f32 {
|
mod_f32 :: proc(x, y: f32) -> (n: f32) {
|
||||||
result: f32;
|
z := abs(y);
|
||||||
y = abs(y);
|
n = remainder(abs(x), z);
|
||||||
result = remainder(abs(x), y);
|
if sign(n) < 0 {
|
||||||
if sign(result) < 0 {
|
n += z;
|
||||||
result += y;
|
|
||||||
}
|
}
|
||||||
return copy_sign(result, x);
|
return copy_sign(n, x);
|
||||||
}
|
}
|
||||||
mod_f64 :: proc(x, y: f64) -> f64 {
|
mod_f64 :: proc(x, y: f64) -> (n: f64) {
|
||||||
result: f64;
|
z := abs(y);
|
||||||
y = abs(y);
|
n = remainder(abs(x), z);
|
||||||
result = remainder(abs(x), y);
|
if sign(n) < 0 {
|
||||||
if sign(result) < 0 {
|
n += z;
|
||||||
result += y;
|
|
||||||
}
|
}
|
||||||
return copy_sign(result, x);
|
return copy_sign(n, x);
|
||||||
}
|
}
|
||||||
mod :: proc{mod_f32, mod_f64};
|
mod :: proc{mod_f32, mod_f64};
|
||||||
|
|
||||||
@@ -452,16 +450,18 @@ mat4_rotate :: proc(v: Vec3, angle_radians: f32) -> Mat4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scale_vec3 :: proc(m: Mat4, v: Vec3) -> Mat4 {
|
scale_vec3 :: proc(m: Mat4, v: Vec3) -> Mat4 {
|
||||||
m[0][0] *= v[0];
|
mm := m;
|
||||||
m[1][1] *= v[1];
|
mm[0][0] *= v[0];
|
||||||
m[2][2] *= v[2];
|
mm[1][1] *= v[1];
|
||||||
|
mm[2][2] *= v[2];
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
scale_f32 :: proc(m: Mat4, s: f32) -> Mat4 {
|
scale_f32 :: proc(m: Mat4, s: f32) -> Mat4 {
|
||||||
m[0][0] *= s;
|
mm := m;
|
||||||
m[1][1] *= s;
|
mm[0][0] *= s;
|
||||||
m[2][2] *= s;
|
mm[1][1] *= s;
|
||||||
|
mm[2][2] *= s;
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -415,16 +415,17 @@ Foreign_Import_Decl :: struct {
|
|||||||
|
|
||||||
|
|
||||||
// Other things
|
// Other things
|
||||||
unparen_expr :: proc(expr: ^Expr) -> ^Expr {
|
unparen_expr :: proc(expr: ^Expr) -> (val: ^Expr) {
|
||||||
|
val = expr;
|
||||||
if expr == nil {
|
if expr == nil {
|
||||||
return nil;
|
return;
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
e, ok := expr.derived.(Paren_Expr);
|
e, ok := val.derived.(Paren_Expr);
|
||||||
if !ok do break;
|
if !ok do break;
|
||||||
expr = e.expr;
|
val = e.expr;
|
||||||
}
|
}
|
||||||
return expr;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Field_Flag :: enum {
|
Field_Flag :: enum {
|
||||||
|
|||||||
@@ -1378,14 +1378,15 @@ parse_field_prefixes :: proc(p: ^Parser) -> ast.Field_Flags {
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_field_flag_prefixes :: proc(p: ^Parser, name_count: int, allowed_flags, set_flags: ast.Field_Flags) -> ast.Field_Flags {
|
check_field_flag_prefixes :: proc(p: ^Parser, name_count: int, allowed_flags, set_flags: ast.Field_Flags) -> (flags: ast.Field_Flags) {
|
||||||
if name_count > 1 && ast.Field_Flag.Using in set_flags {
|
flags = set_flags;
|
||||||
|
if name_count > 1 && ast.Field_Flag.Using in flags {
|
||||||
error(p, p.curr_tok.pos, "cannot apply 'using' to more than one of the same type");
|
error(p, p.curr_tok.pos, "cannot apply 'using' to more than one of the same type");
|
||||||
set_flags &~= {ast.Field_Flag.Using};
|
flags &~= {ast.Field_Flag.Using};
|
||||||
}
|
}
|
||||||
|
|
||||||
for flag in ast.Field_Flag {
|
for flag in ast.Field_Flag {
|
||||||
if flag notin allowed_flags && flag in set_flags {
|
if flag notin allowed_flags && flag in flags {
|
||||||
using ast.Field_Flag;
|
using ast.Field_Flag;
|
||||||
#complete switch flag {
|
#complete switch flag {
|
||||||
case Using:
|
case Using:
|
||||||
@@ -1401,15 +1402,15 @@ check_field_flag_prefixes :: proc(p: ^Parser, name_count: int, allowed_flags, se
|
|||||||
case Ellipsis, Results, Default_Parameters, Typeid_Token:
|
case Ellipsis, Results, Default_Parameters, Typeid_Token:
|
||||||
panic("Impossible prefixes");
|
panic("Impossible prefixes");
|
||||||
}
|
}
|
||||||
set_flags &~= {flag};
|
flags &~= {flag};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ast.Field_Flag.Using in allowed_flags && ast.Field_Flag.Using in set_flags {
|
if ast.Field_Flag.Using in allowed_flags && ast.Field_Flag.Using in flags {
|
||||||
set_flags &~= {ast.Field_Flag.Using};
|
flags &~= {ast.Field_Flag.Using};
|
||||||
}
|
}
|
||||||
|
|
||||||
return set_flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_var_type :: proc(p: ^Parser, flags: ast.Field_Flags) -> ^ast.Expr {
|
parse_var_type :: proc(p: ^Parser, flags: ast.Field_Flags) -> ^ast.Expr {
|
||||||
@@ -1534,7 +1535,7 @@ parse_field_list :: proc(p: ^Parser, follow: token.Kind, allowed_flags: ast.Fiel
|
|||||||
is_signature := (allowed_flags & ast.Field_Flags_Signature_Params) == ast.Field_Flags_Signature_Params;
|
is_signature := (allowed_flags & ast.Field_Flags_Signature_Params) == ast.Field_Flags_Signature_Params;
|
||||||
|
|
||||||
any_polymorphic_names := check_procedure_name_list(p, names);
|
any_polymorphic_names := check_procedure_name_list(p, names);
|
||||||
set_flags = check_field_flag_prefixes(p, len(names), allowed_flags, set_flags);
|
flags := check_field_flag_prefixes(p, len(names), allowed_flags, set_flags);
|
||||||
|
|
||||||
type: ^ast.Expr;
|
type: ^ast.Expr;
|
||||||
default_value: ^ast.Expr;
|
default_value: ^ast.Expr;
|
||||||
@@ -1581,7 +1582,7 @@ parse_field_list :: proc(p: ^Parser, follow: token.Kind, allowed_flags: ast.Fiel
|
|||||||
|
|
||||||
field := new_ast_field(names, type, default_value);
|
field := new_ast_field(names, type, default_value);
|
||||||
field.docs = docs;
|
field.docs = docs;
|
||||||
field.flags = set_flags;
|
field.flags = flags;
|
||||||
field.comment = p.line_comment;
|
field.comment = p.line_comment;
|
||||||
append(fields, field);
|
append(fields, field);
|
||||||
|
|
||||||
@@ -1712,8 +1713,7 @@ string_to_calling_convention :: proc(s: string) -> ast.Proc_Calling_Convention {
|
|||||||
if s[0] != '"' && s[0] != '`' {
|
if s[0] != '"' && s[0] != '`' {
|
||||||
return Invalid;
|
return Invalid;
|
||||||
}
|
}
|
||||||
s = s[1:len(s)-1];
|
switch s[1:len(s)-1] {
|
||||||
switch s {
|
|
||||||
case "odin":
|
case "odin":
|
||||||
return Odin;
|
return Odin;
|
||||||
case "contextless":
|
case "contextless":
|
||||||
@@ -2314,11 +2314,11 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
is_literal_type :: proc(expr: ^ast.Expr) -> bool {
|
is_literal_type :: proc(expr: ^ast.Expr) -> bool {
|
||||||
expr = ast.unparen_expr(expr);
|
val := ast.unparen_expr(expr);
|
||||||
if expr == nil {
|
if val == nil {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switch _ in expr.derived {
|
switch _ in val.derived {
|
||||||
case ast.Bad_Expr,
|
case ast.Bad_Expr,
|
||||||
ast.Ident,
|
ast.Ident,
|
||||||
ast.Selector_Expr,
|
ast.Selector_Expr,
|
||||||
@@ -2452,7 +2452,8 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Call_Expr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
parse_atom_expr :: proc(p: ^Parser, operand: ^ast.Expr, lhs: bool) -> ^ast.Expr {
|
parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^ast.Expr) {
|
||||||
|
operand = value;
|
||||||
if operand == nil {
|
if operand == nil {
|
||||||
if p.allow_type do return nil;
|
if p.allow_type do return nil;
|
||||||
error(p, p.curr_tok.pos, "expected an operand");
|
error(p, p.curr_tok.pos, "expected an operand");
|
||||||
@@ -2462,6 +2463,7 @@ parse_atom_expr :: proc(p: ^Parser, operand: ^ast.Expr, lhs: bool) -> ^ast.Expr
|
|||||||
}
|
}
|
||||||
|
|
||||||
loop := true;
|
loop := true;
|
||||||
|
is_lhs := lhs;
|
||||||
for loop {
|
for loop {
|
||||||
switch p.curr_tok.kind {
|
switch p.curr_tok.kind {
|
||||||
case:
|
case:
|
||||||
@@ -2490,7 +2492,7 @@ parse_atom_expr :: proc(p: ^Parser, operand: ^ast.Expr, lhs: bool) -> ^ast.Expr
|
|||||||
indicies[0] = parse_expr(p, false);
|
indicies[0] = parse_expr(p, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch p.curr.tok.kind {
|
switch p.curr_tok.kind {
|
||||||
case token.Ellipsis, token.Range_Half:
|
case token.Ellipsis, token.Range_Half:
|
||||||
error(p, p.curr_tok.pos, "expected a colon, not a range");
|
error(p, p.curr_tok.pos, "expected a colon, not a range");
|
||||||
fallthrough;
|
fallthrough;
|
||||||
@@ -2566,7 +2568,7 @@ parse_atom_expr :: proc(p: ^Parser, operand: ^ast.Expr, lhs: bool) -> ^ast.Expr
|
|||||||
operand = deref;
|
operand = deref;
|
||||||
|
|
||||||
case token.Open_Brace:
|
case token.Open_Brace:
|
||||||
if !lhs && is_literal_type(operand) && p.expr_level >= 0 {
|
if !is_lhs && is_literal_type(operand) && p.expr_level >= 0 {
|
||||||
operand = parse_literal_value(p, operand);
|
operand = parse_literal_value(p, operand);
|
||||||
} else {
|
} else {
|
||||||
loop = false;
|
loop = false;
|
||||||
@@ -2574,7 +2576,7 @@ parse_atom_expr :: proc(p: ^Parser, operand: ^ast.Expr, lhs: bool) -> ^ast.Expr
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lhs = false;
|
is_lhs = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return operand;
|
return operand;
|
||||||
|
|||||||
@@ -98,9 +98,9 @@ advance_rune :: proc(using t: ^Tokenizer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
peek_byte :: proc(using t: ^Tokenizer, offset := 0) -> byte {
|
peek_byte :: proc(t: ^Tokenizer, offset := 0) -> byte {
|
||||||
if read_offset+offset < len(src) {
|
if t.read_offset+offset < len(t.src) {
|
||||||
return src[read_offset+offset];
|
return t.src[t.read_offset+offset];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -363,8 +363,9 @@ scan_number :: proc(t: ^Tokenizer, seen_decimal_point: bool) -> (token.Kind, str
|
|||||||
|
|
||||||
offset := t.offset;
|
offset := t.offset;
|
||||||
kind := token.Integer;
|
kind := token.Integer;
|
||||||
|
seen_point := seen_decimal_point;
|
||||||
|
|
||||||
if seen_decimal_point {
|
if seen_point {
|
||||||
offset -= 1;
|
offset -= 1;
|
||||||
kind = token.Float;
|
kind = token.Float;
|
||||||
scan_mantissa(t, 10);
|
scan_mantissa(t, 10);
|
||||||
@@ -412,10 +413,10 @@ scan_number :: proc(t: ^Tokenizer, seen_decimal_point: bool) -> (token.Kind, str
|
|||||||
}
|
}
|
||||||
|
|
||||||
case:
|
case:
|
||||||
seen_decimal_point = false;
|
seen_point = false;
|
||||||
scan_mantissa(t, 10);
|
scan_mantissa(t, 10);
|
||||||
if t.ch == '.' {
|
if t.ch == '.' {
|
||||||
seen_decimal_point = true;
|
seen_point = true;
|
||||||
if scan_fraction(t, &kind) {
|
if scan_fraction(t, &kind) {
|
||||||
return kind, string(t.src[offset : t.offset]);
|
return kind, string(t.src[offset : t.offset]);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -96,9 +96,9 @@ quick_sort :: proc(array: $A/[]$T) {
|
|||||||
quick_sort(a[i:n]);
|
quick_sort(a[i:n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_log2 :: proc(n: int) -> int {
|
_log2 :: proc(x: int) -> int {
|
||||||
res := 0;
|
res := 0;
|
||||||
for ; n != 0; n >>= 1 do res += 1;
|
for n := x; n != 0; n >>= 1 do res += 1;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ decode_surrogate_pair :: proc(r1, r2: rune) -> rune {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
encode_surrogate_pair :: proc(r: rune) -> (r1, r2: rune) {
|
encode_surrogate_pair :: proc(c: rune) -> (r1, r2: rune) {
|
||||||
|
r := c;
|
||||||
if r < _surr_self || r > MAX_RUNE {
|
if r < _surr_self || r > MAX_RUNE {
|
||||||
return REPLACEMENT_CHAR, REPLACEMENT_CHAR;
|
return REPLACEMENT_CHAR, REPLACEMENT_CHAR;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user