Skip to content

Commit

Permalink
[cpp] added very basic casts. achieved by new unary operator @ wher…
Browse files Browse the repository at this point in the history
…e rhs is a type name instead of another expression. i accept that this syntax is very odd, but its 1.) easily searchable in text coz its a unique token, and 2.) i think quite readable? if a bit alien
  • Loading branch information
harrand committed May 16, 2024
1 parent 402b20c commit 83ea5d6
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 6 deletions.
4 changes: 4 additions & 0 deletions cpp/src/lex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,10 @@ namespace lex
state.advance(4);
return token{.t = type::operator_defer, .lexeme = "defer"};
}
else if(data.starts_with("@"))
{
return token{.t = type::operator_cast};
}
else if(data.starts_with("?"))
{
return token{.t = type::question_mark};
Expand Down
1 change: 1 addition & 0 deletions cpp/src/lex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ namespace lex
operator_ref,
operator_deref,
operator_defer,
operator_cast,
question_mark,
return_statement,
initialiser,
Expand Down
3 changes: 2 additions & 1 deletion cpp/src/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ namespace parse
|| t.t == lex::type::operator_asterisk
|| t.t == lex::type::operator_slash
|| t.t == lex::type::operator_equals
|| t.t == lex::type::operator_double_equals;
|| t.t == lex::type::operator_double_equals
|| t.t == lex::type::operator_cast;
}
struct subtree
{
Expand Down
17 changes: 16 additions & 1 deletion cpp/src/semal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,19 @@ namespace semal
type binary_operator(const data& d, const ast::binary_operator& payload)
{
type lhs = expression(d, *payload.lhs_expr);
type rhs = expression(d, *payload.rhs_expr);
type rhs = type::undefined();
if(payload.op.t == lex::type::operator_cast)
{
d.assert_that(std::holds_alternative<ast::identifier>(payload.rhs_expr->expr), std::format("in a cast, rhs of the cast token \"{}\" must be an identifier, not an expression or anything else.", payload.op.lexeme));
std::string type_name = std::get<ast::identifier>(payload.rhs_expr->expr).iden;
rhs = d.state.get_type_from_name(type_name);
d.assert_that(!rhs.is_undefined(), std::format("unknown cast destination type \"{}\"", type_name));
// todo: confirm that lhs can actually be casted to rhs.
}
else
{
rhs = expression(d, *payload.rhs_expr);
}
switch(payload.op.t)
{
case lex::type::operator_equals:
Expand All @@ -527,6 +539,9 @@ namespace semal
d.assert_that(lhs == rhs, std::format("both sides of a \"{}\" binary operation must have matching types - passed \"{}\" and \"{}\"", payload.op.lexeme, lhs.name(), rhs.name()));
return type::from_primitive(primitive_type::boolean);
break;
case lex::type::operator_cast:
return rhs;
break;
default:
d.internal_error(std::format("unknown binary operator token \"{}\"", payload.op.lexeme));
break;
Expand Down
9 changes: 5 additions & 4 deletions samples/scratchpad.psy
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ get_data :: () -> mydata
}
//class :: typedef := mydata;

putchar :: (ch : i64) -> u0 := extern;
putchar :: (ch : i8) -> u0 := extern;
dub :: (val : i64) -> i64
{
get_data().member = 5;
//ptr : i8& := __builtin_malloc(123);
//defer __builtin_free(ptr);
ptr : i8& := __builtin_malloc(123@u64);
longptr : i64& := (ptr@i64&);
defer __builtin_free(ptr);

is_cringe : bool := (true == false);
val = deref ref val;
Expand All @@ -51,7 +52,7 @@ dub :: (val : i64) -> i64

complicated :: (par1 : i64, par : i64, par3 : i64) -> i64
{
putchar(-par);
putchar(-par@i8);
}

poggers : i64;
Expand Down

0 comments on commit 83ea5d6

Please sign in to comment.