mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Add inline asm expression to odin/parser
This commit is contained in:
@@ -254,6 +254,27 @@ Auto_Cast :: struct {
|
|||||||
expr: ^Expr,
|
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 = '
|
case .Context, // Also allows for 'context = '
|
||||||
.Proc,
|
.Proc,
|
||||||
.Inline, .No_Inline,
|
.Inline, .No_Inline,
|
||||||
|
.Asm, // Inline assembly
|
||||||
.Ident,
|
.Ident,
|
||||||
.Integer, .Float, .Imag,
|
.Integer, .Float, .Imag,
|
||||||
.Rune, .String,
|
.Rune, .String,
|
||||||
@@ -2595,6 +2596,89 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
|||||||
bst.close = close.pos;
|
bst.close = close.pos;
|
||||||
return bst;
|
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;
|
return nil;
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ Token_Kind :: enum u32 {
|
|||||||
Inline,
|
Inline,
|
||||||
No_Inline,
|
No_Inline,
|
||||||
Context,
|
Context,
|
||||||
|
Asm,
|
||||||
B_Keyword_End,
|
B_Keyword_End,
|
||||||
|
|
||||||
COUNT,
|
COUNT,
|
||||||
@@ -278,6 +279,7 @@ tokens := [Token_Kind.COUNT]string {
|
|||||||
"inline",
|
"inline",
|
||||||
"no_inline",
|
"no_inline",
|
||||||
"context",
|
"context",
|
||||||
|
"asm",
|
||||||
"",
|
"",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user