Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions base/intrinsics/intrinsics.odin
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ constant_utf16_cstring :: proc($literal: string) -> [^]u16 ---

constant_log2 :: proc($v: $T) -> T where type_is_integer(T) ---

constant_floor :: proc($v: $T) -> T where type_is_integer(T) || type_is_float(T) ---
constant_trunc :: proc($v: $T) -> T where type_is_integer(T) || type_is_float(T) ---
constant_ceil :: proc($v: $T) -> T where type_is_integer(T) || type_is_float(T) ---
constant_round :: proc($v: $T) -> T where type_is_integer(T) || type_is_float(T) ---

// SIMD related
simd_add :: proc(a, b: #simd[N]T) -> #simd[N]T ---
simd_sub :: proc(a, b: #simd[N]T) -> #simd[N]T ---
Expand Down
54 changes: 45 additions & 9 deletions src/check_builtin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool
nullptr, // BuiltinProc__type_simple_boolean_begin

is_type_boolean,
is_type_bit_field,
is_type_integer,
is_type_rune,
is_type_float,
Expand All @@ -24,6 +25,7 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool
is_type_cstring16,
is_type_typeid,
is_type_any,

is_type_endian_platform,
is_type_endian_little,
is_type_endian_big,
Expand All @@ -34,8 +36,8 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool
is_type_indexable,
is_type_sliceable,
is_type_comparable,
is_type_simple_compare,
is_type_nearly_simple_compare,
is_type_simple_compare, // easily compared using memcmp
is_type_nearly_simple_compare, // easily compared using memcmp (including floats)
is_type_dereferenceable,
is_type_valid_for_keys,
is_type_valid_for_matrix_elems,
Expand All @@ -47,14 +49,12 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool
is_type_enumerated_array,
is_type_slice,
is_type_dynamic_array,

is_type_map,
is_type_struct,
is_type_union,
is_type_enum,
is_type_proc,
is_type_bit_set,
is_type_bit_field,
is_type_simd_vector,
is_type_matrix,
is_type_raw_union,
Expand Down Expand Up @@ -4768,6 +4768,42 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
break;
}

case BuiltinProc_constant_floor:
case BuiltinProc_constant_trunc:
case BuiltinProc_constant_ceil:
case BuiltinProc_constant_round:
{
Operand o = {};
check_expr(c, &o, ce->args[0]);

if (!is_type_integer_or_float(o.type) && (o.mode != Addressing_Constant)) {
error(ce->args[0], "Expected a constant number for '%.*s'", LIT(builtin_name));
return false;
}
operand->mode = Addressing_Constant;
operand->type = o.type;

ExactValue value = o.value;
if (value.kind == ExactValue_Integer) {
// do nothing
} else if (value.kind == ExactValue_Float) {
f64 f = value.value_float;
switch (id) {
case BuiltinProc_constant_floor: f = floor(f); break;
case BuiltinProc_constant_trunc: f = trunc(f); break;
case BuiltinProc_constant_ceil: f = ceil(f); break;
case BuiltinProc_constant_round: f = round(f); break;
default:
GB_PANIC("Unhandled built-in: %.*s", LIT(builtin_name));
break;
}
value = exact_value_float(f);
}

operand->value = value;
break;
}

case BuiltinProc_soa_struct: {
Operand x = {};
Operand y = {};
Expand Down Expand Up @@ -6552,17 +6588,18 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As


case BuiltinProc_type_is_boolean:
case BuiltinProc_type_is_bit_field:
case BuiltinProc_type_is_integer:
case BuiltinProc_type_is_rune:
case BuiltinProc_type_is_float:
case BuiltinProc_type_is_complex:
case BuiltinProc_type_is_quaternion:
case BuiltinProc_type_is_typeid:
case BuiltinProc_type_is_any:
case BuiltinProc_type_is_string:
case BuiltinProc_type_is_string16:
case BuiltinProc_type_is_cstring:
case BuiltinProc_type_is_cstring16:
case BuiltinProc_type_is_typeid:
case BuiltinProc_type_is_any:
case BuiltinProc_type_is_endian_platform:
case BuiltinProc_type_is_endian_little:
case BuiltinProc_type_is_endian_big:
Expand All @@ -6573,8 +6610,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
case BuiltinProc_type_is_indexable:
case BuiltinProc_type_is_sliceable:
case BuiltinProc_type_is_comparable:
case BuiltinProc_type_is_simple_compare:
case BuiltinProc_type_is_nearly_simple_compare:
case BuiltinProc_type_is_simple_compare: // easily compared using memcmp
case BuiltinProc_type_is_nearly_simple_compare: // easily compared using memcmp (including floats)
case BuiltinProc_type_is_dereferenceable:
case BuiltinProc_type_is_valid_map_key:
case BuiltinProc_type_is_valid_matrix_elements:
Expand All @@ -6591,7 +6628,6 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
case BuiltinProc_type_is_enum:
case BuiltinProc_type_is_proc:
case BuiltinProc_type_is_bit_set:
case BuiltinProc_type_is_bit_field:
case BuiltinProc_type_is_simd_vector:
case BuiltinProc_type_is_matrix:
case BuiltinProc_type_is_raw_union:
Expand Down
21 changes: 15 additions & 6 deletions src/checker_builtin_procs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ enum BuiltinProcId {

BuiltinProc_constant_log2,

BuiltinProc_constant_floor,
BuiltinProc_constant_trunc,
BuiltinProc_constant_ceil,
BuiltinProc_constant_round,

BuiltinProc_transpose,
BuiltinProc_outer_product,
BuiltinProc_hadamard_product,
Expand Down Expand Up @@ -420,7 +425,11 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {

{STR_LIT("has_target_feature"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},

{STR_LIT("constant_log2"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("constant_log2"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("constant_floor"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("constant_trunc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("constant_ceil"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("constant_round"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},

{STR_LIT("transpose"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("outer_product"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
Expand Down Expand Up @@ -615,17 +624,18 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {

{STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_boolean"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_bit_field"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_integer"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_rune"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_float"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_complex"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_quaternion"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_typeid"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_any"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_string"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_string16"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_cstring16"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_cstring16"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_typeid"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_any"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},

{STR_LIT("type_is_endian_platform"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_endian_little"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
Expand Down Expand Up @@ -656,7 +666,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("type_is_enum"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_bit_set"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_bit_field"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_simd_vector"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_matrix"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("type_is_raw_union"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
Expand Down
14 changes: 11 additions & 3 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2739,7 +2739,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
while (allow_token(f, Token_Comma)) {
Ast *dummy_name = parse_ident(f);
if (!err_once) {
error(dummy_name, "'bit_field' fields do not support multiple names per field");
syntax_error(dummy_name, "'bit_field' fields do not support multiple names per field");
err_once = true;
}
}
Expand Down Expand Up @@ -3299,8 +3299,16 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
open = expect_token(f, Token_OpenBracket);

if (f->curr_token.kind == Token_CloseBracket) {
error(f->curr_token, "Expected an operand, got ]");
ERROR_BLOCK();
syntax_error(f->curr_token, "Expected an operand, got ]");
close = expect_token(f, Token_CloseBracket);

if (f->allow_type) {
gbString s = expr_to_string(operand);
error_line("\tSuggestion: If a type was wanted, did you mean '[]%s'?", s);
gb_string_free(s);
}

operand = ast_index_expr(f, operand, nullptr, open, close);
break;
}
Expand Down Expand Up @@ -6594,7 +6602,7 @@ gb_internal bool parse_file_tag(const String &lc, const Token &tok, AstFile *f)
} else if (lc == "no-instrumentation") {
f->flags |= AstFile_NoInstrumentation;
} else {
error(tok, "Unknown tag '%.*s'", LIT(lc));
syntax_error(tok, "Unknown tag '%.*s'", LIT(lc));
}

return true;
Expand Down
9 changes: 9 additions & 0 deletions src/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,15 @@ gb_internal bool is_type_rune(Type *t) {
}
return false;
}
gb_internal bool is_type_integer_or_float(Type *t) {
t = base_type(t);
if (t == nullptr) { return false; }
if (t->kind == Type_Basic) {
return (t->Basic.flags & (BasicFlag_Integer|BasicFlag_Float)) != 0;
}
return false;
}

gb_internal bool is_type_numeric(Type *t) {
t = base_type(t);
if (t == nullptr) { return false; }
Expand Down
1 change: 1 addition & 0 deletions tests/vendor/all.odin
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ package tests_vendor

@(require) import "glfw"
@(require) import _ "lua/5.4"
@(require) import _ "curl"
42 changes: 42 additions & 0 deletions tests/vendor/curl/test_vendor_curl.odin
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#+build windows, linux, darwin
package test_vendor_curl

import "base:runtime"
import "core:testing"
import "vendor:curl"

@(test)
test_curl :: proc(t: ^testing.T) {
data_callback :: proc "c" (contents: [^]byte, size: int, nmemb: int, userp: rawptr) -> int {
context = runtime.default_context()

real_size := size * nmemb
memory := (^[dynamic]byte)(userp)

n := len(memory^)
resize(memory, n + real_size)
copy(memory[n:], contents[:real_size])

return real_size
}


curl.global_init(curl.GLOBAL_ALL)

c := curl.easy_init()
testing.expect(t, c == nil, "curl.easy_init failed")

defer curl.easy_cleanup(c)

memory, memory_err := make([dynamic]byte)
testing.expectf(t, memory_err == nil, "make failed: %v", memory_err)
defer delete(memory)

curl.easy_setopt(c, .URL, cstring("https://odin-lang.org"))
curl.easy_setopt(c, .WRITEFUNCTION, data_callback)
curl.easy_setopt(c, .WRITEDATA, &memory)
curl.easy_setopt(c, .USERAGENT, cstring("libcurl-agent/1.0"))

res := curl.easy_perform(c)
testing.expectf(t, res == nil, "curl.easy_perform failed: %v", res)
}
Loading
Loading