Skip to content

Commit

Permalink
Add support for function types returning no arguments.
Browse files Browse the repository at this point in the history
  • Loading branch information
asoffer committed Dec 29, 2023
1 parent 3488318 commit ab4dead
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 20 deletions.
6 changes: 6 additions & 0 deletions ir/emit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,12 @@ void HandleParseTreeNodeFunctionTypeParameters(ParseNodeIndex index,
.returns = 1});
}

void HandleParseTreeNodeEmptyParenthesis(ParseNodeIndex index,
EmitContext& context) {
jasmin::Value v = type::Bottom;
context.Push(std::span(&v, 1), type::Type_);
}

void HandleParseTreeNodeEnumLiteralStart(ParseNodeIndex, EmitContext&) {
NTH_UNIMPLEMENTED();
}
Expand Down
14 changes: 14 additions & 0 deletions ir/function.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,18 @@ void InvokeForeignFunction::consume(std::span<jasmin::Value> input,
}
}

type::Type ConstructFunctionType::consume(std::span<jasmin::Value, 2> inputs) {
auto parameter = inputs[0].as<type::Type>();
auto return_type = inputs[1].as<type::Type>();
std::vector<type::Type> returns;
if (return_type != type::Bottom) { returns.push_back(return_type); }
if (parameter.kind() == type::Type::Kind::Parameters) {
return type::Function(parameter.AsParameters(), std::move(returns));
} else {
return type::Function(
type::Parameters({{.name = Identifier("").value(), .type = parameter}}),
std::move(returns));
}
}

} // namespace ic
12 changes: 1 addition & 11 deletions ir/function.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,7 @@ struct ConstructParametersType : jasmin::Instruction<ConstructParametersType> {
struct ConstructFunctionType : jasmin::Instruction<ConstructFunctionType> {
static std::string_view name() { return "construct-function-type"; }

static type::Type consume(std::span<jasmin::Value, 2> inputs) {
auto parameter = inputs[0].as<type::Type>();
auto return_type = inputs[1].as<type::Type>();
if (parameter.kind() == type::Type::Kind::Parameters) {
return type::Function(parameter.AsParameters(), std::vector{return_type});
} else {
return type::Function(type::Parameters({{.name = Identifier("").value(),
.type = parameter}}),
std::vector{return_type});
}
}
static type::Type consume(std::span<jasmin::Value, 2> inputs);
};

struct ConstructOpaqueType : jasmin::Instruction<ConstructOpaqueType> {
Expand Down
13 changes: 11 additions & 2 deletions ir/ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,9 @@ void HandleParseTreeNodeExpressionPrecedenceGroup(
});
}
NTH_REQUIRE(context.type_stack().group_count() >= 2);
type::Type return_type = context.type_stack().top()[0].type();
std::span return_types = context.type_stack().top();
std::optional<type::Type> return_type;
if (not return_types.empty()) { return_type = return_types[0].type(); }
context.type_stack().pop();
type::Type parameters_type = context.type_stack().top()[0].type();
auto iter = context.Children(index).begin();
Expand All @@ -485,7 +487,8 @@ void HandleParseTreeNodeExpressionPrecedenceGroup(
});
}

if (return_type != type::Type_) {
if (return_type and return_type != type::Type_) {
NTH_LOG("{}") <<= {return_type};
auto iter = context.Children(index).begin();
diag.Consume({
diag::Header(diag::MessageKind::Error),
Expand Down Expand Up @@ -820,6 +823,12 @@ void HandleParseTreeNodeCallExpression(ParseNodeIndex index, IrContext& context,
}
}

void HandleParseTreeNodeEmptyParenthesis(ParseNodeIndex index,
IrContext& context,
diag::DiagnosticConsumer& diag) {
context.type_stack().push({});
}

void HandleParseTreeNodeDeclaredIdentifier(ParseNodeIndex index,
IrContext& context,
diag::DiagnosticConsumer& diag) {
Expand Down
1 change: 1 addition & 0 deletions parse/node.xmacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ IC_XMACRO_PARSE_NODE_EXPRESSION(Identifier)
IC_XMACRO_PARSE_NODE_EXPRESSION(ExpressionPrecedenceGroup)
IC_XMACRO_PARSE_NODE_EXPRESSION(MemberExpression)
IC_XMACRO_PARSE_NODE_EXPRESSION(EnumLiteral)
IC_XMACRO_PARSE_NODE_EXPRESSION(EmptyParenthesis)

IC_XMACRO_PARSE_NODE_EXPRESSION(Scope)

Expand Down
7 changes: 7 additions & 0 deletions parse/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,13 @@ void Parser::HandleParenthesizedExpression(ParseTree& tree) {
if (current_token().kind() == Token::Kind::LeftParen) {
++iterator_;
IgnoreAnyNewlines();
if (current_token().kind() == Token::Kind::RightParen) {
auto state = pop_state();
tree.append(ParseNode::Kind::EmptyParenthesis, state.token,
state.subtree_start);
++iterator_;
return;
}
ExpandState(Expression(tree), State::Kind::ClosingParenthesis);
} else {
NTH_UNIMPLEMENTED();
Expand Down
2 changes: 1 addition & 1 deletion toolchain/stdlib/compat/c/errno.ic
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
let c ::= import "std.compat.c.types"

let errno ::= builtin.foreign("errno", *c.int)
// let perror ::= builtin.foreign("perror", [*]char -> ())
let perror ::= builtin.foreign("perror", [*]char -> ())
let strerror ::= builtin.foreign("strerror", c.int -> [*]char)
12 changes: 6 additions & 6 deletions toolchain/stdlib/compat/c/stdio.template.ic
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ let fopen ::= builtin.foreign("fopen", ([*]char, [*]char) -> *FILE)
let freopen ::= builtin.foreign("freopen", ([*]char, [*]char, *FILE) -> *FILE)
let fclose ::= builtin.foreign("fclose", *FILE -> c.int)
let fflush ::= builtin.foreign("fflush", *FILE -> c.int)
// let setbuf ::= builtin.foreign("setbuf", (*FILE, [*]char) -> ())
// let setvbuf ::= builtin.foreign("setvbuf", (*FILE, [*]char, c.int, c.size_t) -> c.int)
let setbuf ::= builtin.foreign("setbuf", (*FILE, [*]char) -> ())
let setvbuf ::= builtin.foreign("setvbuf", (*FILE, [*]char, c.int, size_t) -> c.int)

// let fread ::= builtin.foreign("fread", ([*]byte, c.size_t, c.size_t, *FILE) -> c.size_t)
// let fwrite ::= builtin.foreign("fwrite", ([*]byte, c.size_t, c.size_t, *FILE) -> c.size_t)
let fread ::= builtin.foreign("fread", ([*]byte, size_t, size_t, *FILE) -> size_t)
let fwrite ::= builtin.foreign("fwrite", ([*]byte, size_t, size_t, *FILE) -> size_t)

let fgetc ::= builtin.foreign("fgetc", *FILE -> c.int)
let getc ::= builtin.foreign("getc", *FILE -> c.int)
Expand All @@ -48,9 +48,9 @@ let fseek ::= builtin.foreign("fseek", (*FILE, c.long, c.int) -> c.int)
let fsetpos ::= builtin.foreign("fsetpos", (*FILE, *fpos_t) -> c.int)
let rewind ::= builtin.foreign("rewind", *FILE -> c.int)

// let clearerr ::= builtin.foreign("clearerr", *FILE -> ())
let clearerr ::= builtin.foreign("clearerr", *FILE -> ())
let feof ::= builtin.foreign("feof", *FILE -> c.int)
// let ferror ::= builtin.foreign("ferror", *FILE -> ())
let ferror ::= builtin.foreign("ferror", *FILE -> ())
let perror ::= builtin.foreign("perror", [*]char -> c.int)

let remove ::= builtin.foreign("remove", [*]char -> c.int)
Expand Down

0 comments on commit ab4dead

Please sign in to comment.