mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-06 10:44:06 +00:00
Add inline asm expression to odin/parser
This commit is contained in:
@@ -254,6 +254,27 @@ Auto_Cast :: struct {
|
||||
expr: ^Expr,
|
||||
}
|
||||
|
||||
Inline_Asm_Dialect :: enum u8 {
|
||||
Default = 0,
|
||||
ATT = 1,
|
||||
Intel = 2,
|
||||
}
|
||||
|
||||
|
||||
Inline_Asm_Expr :: struct {
|
||||
using node: Expr,
|
||||
tok: tokenizer.Token,
|
||||
param_types: []^Expr,
|
||||
return_type: ^Expr,
|
||||
constraints_string: ^Expr,
|
||||
has_side_effects: bool,
|
||||
is_align_stack: bool,
|
||||
dialect: Inline_Asm_Dialect,
|
||||
open: tokenizer.Pos,
|
||||
asm_string: ^Expr,
|
||||
close: tokenizer.Pos,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1040,6 +1040,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
case .Context, // Also allows for 'context = '
|
||||
.Proc,
|
||||
.Inline, .No_Inline,
|
||||
.Asm, // Inline assembly
|
||||
.Ident,
|
||||
.Integer, .Float, .Imag,
|
||||
.Rune, .String,
|
||||
@@ -2595,6 +2596,89 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
bst.close = close.pos;
|
||||
return bst;
|
||||
|
||||
case .Asm:
|
||||
tok := expect_token(p, .Asm);
|
||||
|
||||
param_types: [dynamic]^ast.Expr
|
||||
return_type: ^ast.Expr;
|
||||
if allow_token(p, .Open_Paren) {
|
||||
for p.curr_tok.kind != .Close_Paren && p.curr_tok.kind != .EOF {
|
||||
t := parse_type(p);
|
||||
append(¶m_types, t);
|
||||
if p.curr_tok.kind != .Comma ||
|
||||
p.curr_tok.kind == .EOF {
|
||||
break;
|
||||
}
|
||||
advance_token(p);
|
||||
}
|
||||
expect_token(p, .Close_Paren);
|
||||
|
||||
if allow_token(p, .Arrow_Right) {
|
||||
return_type = parse_type(p);
|
||||
}
|
||||
}
|
||||
|
||||
has_side_effects := false;
|
||||
is_align_stack := false;
|
||||
dialect := ast.Inline_Asm_Dialect.Default;
|
||||
for allow_token(p, .Hash) {
|
||||
if p.curr_tok.kind == .Ident {
|
||||
name := advance_token(p);
|
||||
switch name.text {
|
||||
case "side_effects":
|
||||
if has_side_effects {
|
||||
error(p, tok.pos, "duplicate directive on inline asm expression: '#side_effects'");
|
||||
}
|
||||
has_side_effects = true;
|
||||
case "align_stack":
|
||||
if is_align_stack {
|
||||
error(p, tok.pos, "duplicate directive on inline asm expression: '#align_stack'");
|
||||
}
|
||||
is_align_stack = true;
|
||||
case "att":
|
||||
if dialect == .ATT {
|
||||
error(p, tok.pos, "duplicate directive on inline asm expression: '#att'");
|
||||
} else if dialect != .Default {
|
||||
error(p, tok.pos, "conflicting asm dialects");
|
||||
} else {
|
||||
dialect = .ATT;
|
||||
}
|
||||
case "intel":
|
||||
if dialect == .Intel {
|
||||
error(p, tok.pos, "duplicate directive on inline asm expression: '#intel'");
|
||||
} else if dialect != .Default {
|
||||
error(p, tok.pos, "conflicting asm dialects");
|
||||
} else {
|
||||
dialect = .Intel;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
error(p, p.curr_tok.pos, "expected an identifier after hash");
|
||||
}
|
||||
}
|
||||
|
||||
open := expect_token(p, .Open_Brace);
|
||||
asm_string := parse_expr(p, false);
|
||||
expect_token(p, .Comma);
|
||||
constraints_string := parse_expr(p, false);
|
||||
allow_token(p, .Comma);
|
||||
close := expect_token(p, .Close_Brace);
|
||||
|
||||
e := ast.new(ast.Inline_Asm_Expr, tok.pos, end_pos(close));
|
||||
e.tok = tok;
|
||||
e.param_types = param_types[:];
|
||||
e.return_type = return_type;
|
||||
e.constraints_string = constraints_string;
|
||||
e.has_side_effects = has_side_effects;
|
||||
e.is_align_stack = is_align_stack;
|
||||
e.dialect = dialect;
|
||||
e.open = open.pos;
|
||||
e.asm_string = asm_string;
|
||||
e.close = close.pos;
|
||||
|
||||
return e;
|
||||
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
||||
@@ -149,6 +149,7 @@ Token_Kind :: enum u32 {
|
||||
Inline,
|
||||
No_Inline,
|
||||
Context,
|
||||
Asm,
|
||||
B_Keyword_End,
|
||||
|
||||
COUNT,
|
||||
@@ -278,6 +279,7 @@ tokens := [Token_Kind.COUNT]string {
|
||||
"inline",
|
||||
"no_inline",
|
||||
"context",
|
||||
"asm",
|
||||
"",
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user