Pointers wip
This commit is contained in:
parent
776c12f6b5
commit
0c11b09548
16 changed files with 234 additions and 17 deletions
|
|
@ -1,8 +1,13 @@
|
||||||
func print(c: u8):
|
func alloc(size: u64) -> unit mut*:
|
||||||
foreign func putchar(c: i32) -> i32
|
foreign func malloc(size: u64) -> unit mut*
|
||||||
putchar(c as i32)
|
return malloc(size)
|
||||||
|
|
||||||
mut a = 10ub
|
foreign func free(ptr: unit*)
|
||||||
let b = a
|
|
||||||
a = 11ub
|
let array = alloc(400ul) as i32 mut*
|
||||||
print(b)
|
*array = 10
|
||||||
|
*(array + 1) = 20
|
||||||
|
let q = array + 10
|
||||||
|
let n = q - array
|
||||||
|
array[5] = 50
|
||||||
|
free(array as unit*)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@ namespace pslang::ast
|
||||||
{
|
{
|
||||||
negation,
|
negation,
|
||||||
logical_not,
|
logical_not,
|
||||||
|
address_of,
|
||||||
|
mutable_address_of,
|
||||||
|
dereference,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class binary_operation_type
|
enum class binary_operation_type
|
||||||
|
|
@ -40,6 +43,15 @@ namespace pslang::ast
|
||||||
case unary_operation_type::logical_not:
|
case unary_operation_type::logical_not:
|
||||||
out << "not";
|
out << "not";
|
||||||
break;
|
break;
|
||||||
|
case unary_operation_type::address_of:
|
||||||
|
out << "address of";
|
||||||
|
break;
|
||||||
|
case unary_operation_type::mutable_address_of:
|
||||||
|
out << "mutable address of";
|
||||||
|
break;
|
||||||
|
case unary_operation_type::dereference:
|
||||||
|
out << "dereference";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,13 @@ namespace pslang::ast
|
||||||
types::type_ptr inferred_type = nullptr;
|
types::type_ptr inferred_type = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct pointer_type
|
||||||
|
{
|
||||||
|
type_ptr referenced_type;
|
||||||
|
bool is_mutable;
|
||||||
|
types::type_ptr inferred_type = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
struct type_identifier
|
struct type_identifier
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
@ -42,6 +49,7 @@ namespace pslang::ast
|
||||||
types::primitive_type,
|
types::primitive_type,
|
||||||
array_type,
|
array_type,
|
||||||
function_type,
|
function_type,
|
||||||
|
pointer_type,
|
||||||
type_identifier
|
type_identifier
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,14 @@ namespace pslang::ast
|
||||||
{
|
{
|
||||||
out << type.node->name;
|
out << type.node->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void apply(types::pointer_type const & type)
|
||||||
|
{
|
||||||
|
apply(*type.referenced_type);
|
||||||
|
if (type.is_mutable)
|
||||||
|
out << " mut";
|
||||||
|
out << "*";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct type_print_visitor
|
struct type_print_visitor
|
||||||
|
|
@ -178,6 +186,14 @@ namespace pslang::ast
|
||||||
apply(*type.result);
|
apply(*type.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void apply(pointer_type const & type)
|
||||||
|
{
|
||||||
|
apply(*type.referenced_type);
|
||||||
|
if (type.is_mutable)
|
||||||
|
out << " mut";
|
||||||
|
out << "*";
|
||||||
|
}
|
||||||
|
|
||||||
void apply(type_identifier const & type)
|
void apply(type_identifier const & type)
|
||||||
{
|
{
|
||||||
out << type.name;
|
out << type.name;
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,11 @@ namespace pslang::ast
|
||||||
apply(*function_type.result);
|
apply(*function_type.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void apply(pointer_type const & pointer_type)
|
||||||
|
{
|
||||||
|
apply(*pointer_type.referenced_type);
|
||||||
|
}
|
||||||
|
|
||||||
void apply(type_identifier & identifier)
|
void apply(type_identifier & identifier)
|
||||||
{
|
{
|
||||||
for (auto it = scopes.rbegin(); it != scopes.rend(); ++it)
|
for (auto it = scopes.rbegin(); it != scopes.rend(); ++it)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,11 @@ namespace pslang::ast
|
||||||
return type.inferred_type;
|
return type.inferred_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
types::type_ptr apply(ast::pointer_type const & type)
|
||||||
|
{
|
||||||
|
return type.inferred_type;
|
||||||
|
}
|
||||||
|
|
||||||
types::type_ptr apply(ast::type_identifier const & type)
|
types::type_ptr apply(ast::type_identifier const & type)
|
||||||
{
|
{
|
||||||
return type.inferred_type;
|
return type.inferred_type;
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,11 @@ namespace pslang::ast
|
||||||
return {.size = 8, .alignment = 8};
|
return {.size = 8, .alignment = 8};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_and_alignment apply(types::pointer_type const & type)
|
||||||
|
{
|
||||||
|
return {.size = 8, .alignment = 8};
|
||||||
|
}
|
||||||
|
|
||||||
size_and_alignment apply(types::struct_type const & type)
|
size_and_alignment apply(types::struct_type const & type)
|
||||||
{
|
{
|
||||||
if (auto jt = lcontext.structs.find(type.node); jt != lcontext.structs.end())
|
if (auto jt = lcontext.structs.find(type.node); jt != lcontext.structs.end())
|
||||||
|
|
@ -136,6 +141,12 @@ namespace pslang::ast
|
||||||
node.inferred_type = std::make_unique<types::type>(std::move(type));
|
node.inferred_type = std::make_unique<types::type>(std::move(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void apply(ast::pointer_type & node)
|
||||||
|
{
|
||||||
|
apply(*node.referenced_type);
|
||||||
|
node.inferred_type = std::make_unique<types::type>(types::pointer_type{get_type(*node.referenced_type), node.is_mutable});
|
||||||
|
}
|
||||||
|
|
||||||
void apply(ast::type_identifier & node)
|
void apply(ast::type_identifier & node)
|
||||||
{
|
{
|
||||||
node.inferred_type = std::make_unique<types::type>(types::struct_type{node.node});
|
node.inferred_type = std::make_unique<types::type>(types::struct_type{node.node});
|
||||||
|
|
@ -272,6 +283,46 @@ namespace pslang::ast
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case unary_operation_type::address_of:
|
||||||
|
if (auto lvalue = classify_lvalue(node.arg1))
|
||||||
|
{
|
||||||
|
switch (*lvalue)
|
||||||
|
{
|
||||||
|
case ast::value_category::compile_time:
|
||||||
|
throw type_error("Cannot take address of a compile-time value", node.location);
|
||||||
|
case ast::value_category::constant:
|
||||||
|
case ast::value_category::_mutable:
|
||||||
|
node.inferred_type = std::make_unique<types::type>(types::pointer_type{arg1_type, false});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw type_error("Cannot take address of a non-lvalue", node.location);
|
||||||
|
break;
|
||||||
|
case unary_operation_type::mutable_address_of:
|
||||||
|
if (auto lvalue = classify_lvalue(node.arg1))
|
||||||
|
{
|
||||||
|
switch (*lvalue)
|
||||||
|
{
|
||||||
|
case ast::value_category::compile_time:
|
||||||
|
throw type_error("Cannot take address of a compile-time value", node.location);
|
||||||
|
case ast::value_category::constant:
|
||||||
|
throw type_error("Cannot take mutable address of an immutable value", node.location);
|
||||||
|
case ast::value_category::_mutable:
|
||||||
|
node.inferred_type = std::make_unique<types::type>(types::pointer_type{arg1_type, true});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw type_error("Cannot take address of a non-lvalue", node.location);
|
||||||
|
break;
|
||||||
|
case unary_operation_type::dereference:
|
||||||
|
if (auto pointer_type = std::get_if<types::pointer_type>(arg1_type.get()))
|
||||||
|
{
|
||||||
|
node.inferred_type = pointer_type->referenced_type;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
|
@ -298,6 +349,16 @@ namespace pslang::ast
|
||||||
node.inferred_type = arg1_type;
|
node.inferred_type = arg1_type;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (types::is_pointer_type(*arg1_type) && types::is_integer_type(*arg2_type))
|
||||||
|
{
|
||||||
|
node.inferred_type = arg1_type;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (types::is_integer_type(*arg1_type) && types::is_pointer_type(*arg2_type))
|
||||||
|
{
|
||||||
|
node.inferred_type = arg1_type;
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case binary_operation_type::subtraction:
|
case binary_operation_type::subtraction:
|
||||||
if (equal && types::is_numeric_type(*arg1_type))
|
if (equal && types::is_numeric_type(*arg1_type))
|
||||||
|
|
@ -305,6 +366,16 @@ namespace pslang::ast
|
||||||
node.inferred_type = arg1_type;
|
node.inferred_type = arg1_type;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (types::is_pointer_type(*arg1_type) && types::is_integer_type(*arg2_type))
|
||||||
|
{
|
||||||
|
node.inferred_type = arg1_type;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (types::is_pointer_type(*arg1_type) && types::is_pointer_type(*arg2_type))
|
||||||
|
{
|
||||||
|
node.inferred_type = std::make_unique<types::type>(types::primitive_type{types::i64_type{}});
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case binary_operation_type::multiplication:
|
case binary_operation_type::multiplication:
|
||||||
if (equal && types::is_numeric_type(*arg1_type))
|
if (equal && types::is_numeric_type(*arg1_type))
|
||||||
|
|
@ -431,6 +502,16 @@ namespace pslang::ast
|
||||||
if (!types::is_bool_type(*source_type) && !types::is_bool_type(*target_type))
|
if (!types::is_bool_type(*source_type) && !types::is_bool_type(*target_type))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (auto source_pointer_type = std::get_if<types::pointer_type>(source_type.get()))
|
||||||
|
{
|
||||||
|
if (auto target_pointer_type = std::get_if<types::pointer_type>(target_type.get()))
|
||||||
|
{
|
||||||
|
if (!source_pointer_type->is_mutable && target_pointer_type->is_mutable)
|
||||||
|
throw type_error("Cannot cast an immutable pointer to a mutable pointer", node.location);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << "Cannot cast a value of type ";
|
os << "Cannot cast a value of type ";
|
||||||
print(os, *source_type);
|
print(os, *source_type);
|
||||||
|
|
@ -592,17 +673,22 @@ namespace pslang::ast
|
||||||
throw type_error(os.str(), get_location(*node.index));
|
throw type_error(os.str(), get_location(*node.index));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto atype = std::get_if<types::array_type>(array_type.get());
|
if (auto atype = std::get_if<types::array_type>(array_type.get()))
|
||||||
|
|
||||||
if (!atype)
|
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
node.inferred_type = atype->element_type;
|
||||||
os << "Expected an array to index, but got ";
|
return;
|
||||||
print(os, *array_type);
|
|
||||||
throw type_error(os.str(), get_location(*node.array));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node.inferred_type = atype->element_type;
|
if (auto ptype = std::get_if<types::pointer_type>(array_type.get()))
|
||||||
|
{
|
||||||
|
node.inferred_type = ptype->referenced_type;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Expected an array or a pointer, but got ";
|
||||||
|
print(os, *array_type);
|
||||||
|
throw type_error(os.str(), get_location(*node.array));
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply(field_access & node)
|
void apply(field_access & node)
|
||||||
|
|
@ -785,7 +871,30 @@ namespace pslang::ast
|
||||||
}
|
}
|
||||||
else if (auto array_access = std::get_if<ast::array_access>(node.get()))
|
else if (auto array_access = std::get_if<ast::array_access>(node.get()))
|
||||||
{
|
{
|
||||||
return classify_lvalue(array_access->array);
|
auto array_type = get_type(*array_access->array);
|
||||||
|
if (std::get_if<types::array_type>(array_type.get()))
|
||||||
|
return classify_lvalue(array_access->array);
|
||||||
|
if (auto pointer_type = std::get_if<types::pointer_type>(array_type.get()))
|
||||||
|
{
|
||||||
|
if (pointer_type->is_mutable)
|
||||||
|
return ast::value_category::_mutable;
|
||||||
|
else
|
||||||
|
return ast::value_category::constant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (auto unary_operation = std::get_if<ast::unary_operation>(node.get()))
|
||||||
|
{
|
||||||
|
if (unary_operation->type == ast::unary_operation_type::dereference)
|
||||||
|
{
|
||||||
|
auto arg_type = get_type(*unary_operation->arg1);
|
||||||
|
if (auto pointer_type = std::get_if<types::pointer_type>(arg_type.get()))
|
||||||
|
{
|
||||||
|
if (pointer_type->is_mutable)
|
||||||
|
return ast::value_category::_mutable;
|
||||||
|
else
|
||||||
|
return ast::value_category::constant;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,11 @@ namespace pslang::interpreter
|
||||||
throw std::runtime_error("Cannot zero-initialize a function type");
|
throw std::runtime_error("Cannot zero-initialize a function type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value apply(types::pointer_type const &)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
value apply(types::struct_type const & struct_type)
|
value apply(types::struct_type const & struct_type)
|
||||||
{
|
{
|
||||||
struct_value result{.struct_type = std::make_unique<types::type>(struct_type)};
|
struct_value result{.struct_type = std::make_unique<types::type>(struct_type)};
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,10 @@ namespace pslang::interpreter
|
||||||
return primitive_value(primitive_value_base<T>{static_cast<T>(~arg1.value)});
|
return primitive_value(primitive_value_base<T>{static_cast<T>(~arg1.value)});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ast::unary_operation_type::address_of:
|
||||||
|
case ast::unary_operation_type::mutable_address_of:
|
||||||
|
case ast::unary_operation_type::dereference:
|
||||||
|
throw std::runtime_error("Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,15 @@ namespace pslang::ir
|
||||||
case ast::unary_operation_type::logical_not:
|
case ast::unary_operation_type::logical_not:
|
||||||
out << "not";
|
out << "not";
|
||||||
break;
|
break;
|
||||||
|
case ast::unary_operation_type::address_of:
|
||||||
|
out << "address";
|
||||||
|
break;
|
||||||
|
case ast::unary_operation_type::mutable_address_of:
|
||||||
|
out << "address";
|
||||||
|
break;
|
||||||
|
case ast::unary_operation_type::dereference:
|
||||||
|
out << "deref";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -586,6 +586,10 @@ namespace pslang::jit::aarch64
|
||||||
if (types::is_integer_type(*node.inferred_type))
|
if (types::is_integer_type(*node.inferred_type))
|
||||||
extend(0, node.inferred_type);
|
extend(0, node.inferred_type);
|
||||||
break;
|
break;
|
||||||
|
case ast::unary_operation_type::address_of:
|
||||||
|
case ast::unary_operation_type::mutable_address_of:
|
||||||
|
case ast::unary_operation_type::dereference:
|
||||||
|
throw std::runtime_error("Not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,7 @@ template <typename T>
|
||||||
%precedence UMINUS
|
%precedence UMINUS
|
||||||
%left asterisk slash percent
|
%left asterisk slash percent
|
||||||
%precedence NOT
|
%precedence NOT
|
||||||
|
%precedence ADDRESSOF DEREFERENCE
|
||||||
%precedence lbracket
|
%precedence lbracket
|
||||||
|
|
||||||
%type <indented_statement_list> indented_statement_list
|
%type <indented_statement_list> indented_statement_list
|
||||||
|
|
@ -268,6 +269,8 @@ type_expression
|
||||||
| type_expression arrow type_expression { std::vector<ast::type_ptr> args; args.push_back(std::make_unique<ast::type>($1)); $$ = ast::function_type{std::move(args), std::make_unique<ast::type>($3)}; }
|
| type_expression arrow type_expression { std::vector<ast::type_ptr> args; args.push_back(std::make_unique<ast::type>($1)); $$ = ast::function_type{std::move(args), std::make_unique<ast::type>($3)}; }
|
||||||
| lparen function_paren_type_list rparen arrow type_expression { $$ = ast::function_type{$2, std::make_unique<ast::type>($5)}; }
|
| lparen function_paren_type_list rparen arrow type_expression { $$ = ast::function_type{$2, std::make_unique<ast::type>($5)}; }
|
||||||
| lparen type_expression rparen { $$ = $2; }
|
| lparen type_expression rparen { $$ = $2; }
|
||||||
|
| type_expression asterisk { $$ = ast::pointer_type{std::make_unique<ast::type>($1), false}; }
|
||||||
|
| type_expression mut asterisk { $$ = ast::pointer_type{std::make_unique<ast::type>($1), true}; }
|
||||||
;
|
;
|
||||||
|
|
||||||
primitive_type
|
primitive_type
|
||||||
|
|
@ -315,6 +318,9 @@ expression
|
||||||
| expression slash expression { $$ = ast::binary_operation{ast::binary_operation_type::division, std::make_unique<ast::expression>($1), std::make_unique<ast::expression>($3), @$ }; }
|
| expression slash expression { $$ = ast::binary_operation{ast::binary_operation_type::division, std::make_unique<ast::expression>($1), std::make_unique<ast::expression>($3), @$ }; }
|
||||||
| expression percent expression { $$ = ast::binary_operation{ast::binary_operation_type::remainder, std::make_unique<ast::expression>($1), std::make_unique<ast::expression>($3), @$ }; }
|
| expression percent expression { $$ = ast::binary_operation{ast::binary_operation_type::remainder, std::make_unique<ast::expression>($1), std::make_unique<ast::expression>($3), @$ }; }
|
||||||
| exclamation expression %prec NOT { $$ = ast::unary_operation{ast::unary_operation_type::logical_not, std::make_unique<ast::expression>($2), @$ }; }
|
| exclamation expression %prec NOT { $$ = ast::unary_operation{ast::unary_operation_type::logical_not, std::make_unique<ast::expression>($2), @$ }; }
|
||||||
|
| ampersand expression %prec ADDRESSOF { $$ = ast::unary_operation{ast::unary_operation_type::address_of, std::make_unique<ast::expression>($2), @$ }; }
|
||||||
|
| ampersand mut expression %prec ADDRESSOF { $$ = ast::unary_operation{ast::unary_operation_type::mutable_address_of, std::make_unique<ast::expression>($3), @$ }; }
|
||||||
|
| asterisk expression %prec DEREFERENCE { $$ = ast::unary_operation{ast::unary_operation_type::dereference, std::make_unique<ast::expression>($2), @$ }; }
|
||||||
| postfix_expression { $$ = $1; }
|
| postfix_expression { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
19
libs/types/include/pslang/types/pointer.hpp
Normal file
19
libs/types/include/pslang/types/pointer.hpp
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pslang/types/type_fwd.hpp>
|
||||||
|
|
||||||
|
namespace pslang::types
|
||||||
|
{
|
||||||
|
|
||||||
|
struct pointer_type
|
||||||
|
{
|
||||||
|
type_ptr referenced_type;
|
||||||
|
bool is_mutable;
|
||||||
|
|
||||||
|
friend bool operator == (pointer_type const & t1, pointer_type const & t2)
|
||||||
|
{
|
||||||
|
return equal(*t1.referenced_type, *t2.referenced_type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <pslang/types/array.hpp>
|
#include <pslang/types/array.hpp>
|
||||||
#include <pslang/types/function.hpp>
|
#include <pslang/types/function.hpp>
|
||||||
#include <pslang/types/struct.hpp>
|
#include <pslang/types/struct.hpp>
|
||||||
|
#include <pslang/types/pointer.hpp>
|
||||||
#include <pslang/types/type_fwd.hpp>
|
#include <pslang/types/type_fwd.hpp>
|
||||||
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
@ -17,7 +18,8 @@ namespace pslang::types
|
||||||
primitive_type,
|
primitive_type,
|
||||||
array_type,
|
array_type,
|
||||||
function_type,
|
function_type,
|
||||||
struct_type
|
struct_type,
|
||||||
|
pointer_type
|
||||||
>;
|
>;
|
||||||
|
|
||||||
struct type
|
struct type
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ namespace pslang::types
|
||||||
bool is_numeric_type(type const & type);
|
bool is_numeric_type(type const & type);
|
||||||
bool is_builtin_type(type const & type);
|
bool is_builtin_type(type const & type);
|
||||||
bool is_function_type(type const & type);
|
bool is_function_type(type const & type);
|
||||||
|
bool is_pointer_type(type const & type);
|
||||||
|
|
||||||
std::size_t type_size(type const & type);
|
std::size_t type_size(type const & type);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,13 @@ namespace pslang::types
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_pointer_type(type const & type)
|
||||||
|
{
|
||||||
|
if (std::get_if<pointer_type>(&type))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t type_size(type const & type)
|
std::size_t type_size(type const & type)
|
||||||
{
|
{
|
||||||
if (std::get_if<unit_type>(&type))
|
if (std::get_if<unit_type>(&type))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue