function pointers and callbacks
This commit is contained in:
@@ -90,7 +90,7 @@ is_type_token :: proc(kind: token.Kind) -> bool {
|
||||
.Keyword_C_Short, .Keyword_C_Ushort, .Keyword_C_Int, .Keyword_C_Uint,
|
||||
.Keyword_C_Long, .Keyword_C_Ulong, .Keyword_C_Longlong, .Keyword_C_Ulonglong,
|
||||
.Keyword_C_Float, .Keyword_C_Double, .Keyword_C_Longdouble,
|
||||
.Keyword_Void, .Identifier, .Question, .At, .Star, .Left_Bracket:
|
||||
.Keyword_Void, .Keyword_C_Func, .Identifier, .Question, .At, .Star, .Left_Bracket:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -291,6 +291,25 @@ parse_type :: proc(parser: ^Parser) -> ast.Type_Syntax {
|
||||
case .Keyword_Void:
|
||||
advance(parser)
|
||||
return types.VOID
|
||||
case .Keyword_C_Func:
|
||||
advance(parser)
|
||||
if _, ok := allow(parser, .Left_Paren); !ok {
|
||||
source.add(parser.diagnostics, current(parser).span, "expected '(' after c_func type")
|
||||
return types.INVALID
|
||||
}
|
||||
params, variadic := parse_params(parser)
|
||||
if _, ok := allow(parser, .Right_Paren); !ok {
|
||||
source.add(parser.diagnostics, current(parser).span, "expected ')' after function type parameters")
|
||||
}
|
||||
result := parse_type(parser)
|
||||
param_types := make([]types.Type, len(params), parser.module.allocator)
|
||||
for param, index in params {
|
||||
param_types[index] = param.type
|
||||
}
|
||||
function_type := types.function(&parser.module.type_store, param_types, result, true, variadic)
|
||||
delete(param_types, parser.module.allocator)
|
||||
delete(params, parser.module.allocator)
|
||||
return function_type
|
||||
case .Identifier:
|
||||
first := advance(parser)
|
||||
name := first
|
||||
@@ -334,11 +353,7 @@ skip_parenthesized :: proc(parser: ^Parser) -> source.Span {
|
||||
return span_from(start.span, end.span)
|
||||
}
|
||||
|
||||
parse_call :: proc(parser: ^Parser, qualifier: symbol.Id, first, name: token.Token, nesting: int) -> ast.Expr_Id {
|
||||
if nesting >= MAX_EXPRESSION_NESTING {
|
||||
span := skip_parenthesized(parser)
|
||||
return invalid_expr(parser, span, "expression nesting exceeds 256 levels")
|
||||
}
|
||||
parse_call_args :: proc(parser: ^Parser, nesting: int) -> ([]ast.Expr_Id, token.Token) {
|
||||
left_paren := advance(parser)
|
||||
parser.delimiter_depth += 1
|
||||
defer parser.delimiter_depth -= 1
|
||||
@@ -359,6 +374,15 @@ parse_call :: proc(parser: ^Parser, qualifier: symbol.Id, first, name: token.Tok
|
||||
source.add(parser.diagnostics, current(parser).span, "expected ')' after call arguments")
|
||||
right_paren = left_paren
|
||||
}
|
||||
return args[:], right_paren
|
||||
}
|
||||
|
||||
parse_call :: proc(parser: ^Parser, qualifier: symbol.Id, first, name: token.Token, nesting: int) -> ast.Expr_Id {
|
||||
if nesting >= MAX_EXPRESSION_NESTING {
|
||||
span := skip_parenthesized(parser)
|
||||
return invalid_expr(parser, span, "expression nesting exceeds 256 levels")
|
||||
}
|
||||
args, right_paren := parse_call_args(parser, nesting)
|
||||
return add_expr(parser, ast.Expr{
|
||||
kind=.Call,
|
||||
span=source.Span{file=name.span.file, start=first.span.start, end=right_paren.span.end},
|
||||
@@ -735,6 +759,24 @@ parse_expression_bp :: proc(parser: ^Parser, minimum_binding_power, nesting: int
|
||||
}
|
||||
continue
|
||||
}
|
||||
if current(parser).kind == .Left_Paren {
|
||||
if nesting >= MAX_EXPRESSION_NESTING {
|
||||
span := skip_parenthesized(parser)
|
||||
left = invalid_expr(parser, span, "expression nesting exceeds 256 levels")
|
||||
continue
|
||||
}
|
||||
left_expr := parser.module.exprs[left]
|
||||
args, right_paren := parse_call_args(parser, nesting)
|
||||
left = add_expr(parser, ast.Expr{
|
||||
kind=.Call,
|
||||
span=span_from(left_expr.span, right_paren.span),
|
||||
args=args,
|
||||
left=left,
|
||||
right=ast.INVALID_EXPR,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
continue
|
||||
}
|
||||
left_power, right_power, ok := infix_binding_power(current(parser).kind)
|
||||
if !ok || left_power < minimum_binding_power {
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user