Skip to content

Commit f54730d

Browse files
committed
Fix parse_variadic_add3 test
Parsing/printing the function AST wasn't really working before this.
1 parent 83b16ea commit f54730d

File tree

5 files changed

+111
-13
lines changed

5 files changed

+111
-13
lines changed

src/ast/functions.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,19 +357,31 @@ regular_insn_common!(CallInstruction);
357357
/// An argument to a [`CallInstruction`].
358358
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
359359
pub enum CallArgument {
360-
Value(Value),
360+
Regular(RegularCallArgument),
361361
Environment(Value),
362362
VariadicMarker(Span),
363363
}
364364
impl Display for CallArgument {
365365
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
366366
match self {
367-
CallArgument::Value(value) => Display::fmt(value, f),
367+
CallArgument::Regular(inner) => Display::fmt(inner, f),
368368
CallArgument::Environment(value) => write!(f, "env {value}"),
369369
CallArgument::VariadicMarker(_) => f.write_str("..."),
370370
}
371371
}
372372
}
373+
/// A regular [`CallArgument`], including both a value and its type.
374+
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
375+
pub struct RegularCallArgument {
376+
pub span: Span,
377+
pub ty: AbiType,
378+
pub value: Value,
379+
}
380+
impl Display for RegularCallArgument {
381+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
382+
write!(f, "{} {}", self.ty, self.value)
383+
}
384+
}
373385

374386
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
375387
pub struct ThreadLocalRef {

src/ast/functions/parse.rs

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::ast::data::Constant;
22
use crate::ast::functions::{
3-
EnvironmentParamDef, FunctionBlock, FunctionBody, FunctionDef, InsnDestInfo, JumpInstruction,
4-
JumpInstructionKind, ParamDef, PhiArg, PhiInstruction, RegularInstruction, RegularParamDef,
5-
SimpleInstruction, SimpleInstructionArgs, ThreadLocalRef, Value, VariadicParamDef,
3+
CallArgument, CallInstruction, EnvironmentParamDef, FunctionBlock, FunctionBody, FunctionDef,
4+
InsnDestInfo, JumpInstruction, JumpInstructionKind, ParamDef, PhiArg, PhiInstruction,
5+
RegularCallArgument, RegularInstruction, RegularParamDef, SimpleInstruction,
6+
SimpleInstructionArgs, ThreadLocalRef, Value, VariadicParamDef,
67
};
78
use crate::ast::linkage::Linkage;
89
use crate::ast::types::{AbiType, BaseType};
@@ -114,7 +115,7 @@ impl Parse for RegularParamDef {
114115
impl Parse for EnvironmentParamDef {
115116
const DESC: &'static str = "environment parameter";
116117
fn parser<'a>() -> impl TokenParser<'a, Self> {
117-
operator!(...)
118+
keyword!(env)
118119
.parser()
119120
.ignore_then(TemporaryName::parser())
120121
.map_with(|name, extra| EnvironmentParamDef {
@@ -269,9 +270,11 @@ impl Parse for PhiArg {
269270
impl Parse for RegularInstruction {
270271
const DESC: &'static str = "regular instruction";
271272
fn parser<'a>() -> impl TokenParser<'a, Self> {
272-
SimpleInstruction::parser()
273-
.map(RegularInstruction::Simple)
274-
.labelled(Self::DESC)
273+
choice((
274+
SimpleInstruction::parser().map(RegularInstruction::Simple),
275+
CallInstruction::parser().map(RegularInstruction::Call),
276+
))
277+
.labelled(Self::DESC)
275278
}
276279
}
277280
impl_fromstr_via_parse!(RegularInstruction);
@@ -298,6 +301,57 @@ impl Parse for SimpleInstruction {
298301
}
299302
}
300303
impl_fromstr_via_parse!(SimpleInstruction);
304+
impl Parse for CallInstruction {
305+
const DESC: &'static str = "call instruction";
306+
fn parser<'a>() -> impl TokenParser<'a, Self> {
307+
let args = CallArgument::parser()
308+
.separated_by(operator!(,).parser())
309+
.collect::<Vec<_>>()
310+
.delimited_by(just(Token::OpenParen), just(Token::CloseParen));
311+
InsnDestInfo::parser()
312+
.or_not()
313+
.then(keyword!(call).parser().to_span())
314+
.then(Value::parser())
315+
.then(args)
316+
.map_with(
317+
|(((dest_info, call_kw_span), target), args), extra| CallInstruction {
318+
span: extra.span(),
319+
call_kw_span,
320+
target,
321+
args,
322+
dest_info,
323+
},
324+
)
325+
}
326+
}
327+
impl Parse for CallArgument {
328+
const DESC: &'static str = "call argument";
329+
fn parser<'a>() -> impl TokenParser<'a, Self> {
330+
choice((
331+
RegularCallArgument::parser().map(CallArgument::Regular),
332+
keyword!(env)
333+
.parser()
334+
.ignore_then(Value::parser())
335+
.map(CallArgument::Environment),
336+
operator!(...)
337+
.parser()
338+
.to_span()
339+
.map(CallArgument::VariadicMarker),
340+
))
341+
}
342+
}
343+
impl Parse for RegularCallArgument {
344+
const DESC: &'static str = "regular call argument";
345+
fn parser<'a>() -> impl TokenParser<'a, Self> {
346+
AbiType::parser()
347+
.then(Value::parser())
348+
.map_with(|(ty, value), extra| RegularCallArgument {
349+
ty,
350+
value,
351+
span: extra.span(),
352+
})
353+
}
354+
}
301355
impl Parse for InsnDestInfo {
302356
const DESC: &'static str = "instruction destination";
303357
fn parser<'a>() -> impl TokenParser<'a, Self> {

src/ast/functions/test.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
use crate::ast::data::Constant;
12
use crate::ast::functions::{
2-
FunctionBlock, FunctionBody, FunctionDef, InsnDestInfo, JumpInstruction, ParamDef, PhiArg,
3-
PhiInstruction, RegularInstruction, RegularParamDef, SimpleInstruction, SimpleInstructionArgs,
4-
Value, VariadicParamDef,
3+
CallArgument, CallInstruction, FunctionBlock, FunctionBody, FunctionDef, InsnDestInfo,
4+
JumpInstruction, ParamDef, PhiArg, PhiInstruction, RegularCallArgument, RegularInstruction,
5+
RegularParamDef, SimpleInstruction, SimpleInstructionArgs, Value, VariadicParamDef,
56
};
67
use crate::ast::linkage::Linkage;
78
use crate::ast::types::BaseType;
@@ -139,6 +140,36 @@ fn variadic_add3() -> FunctionDef {
139140
args: SimpleInstructionArgs::from([32.into()]),
140141
}
141142
.into(),
143+
SimpleInstruction {
144+
span: Span::MISSING,
145+
dest_info: None,
146+
name: Ident::unspanned("vastart"),
147+
args: SimpleInstructionArgs::from([TemporaryName::unspanned("ap").into()]),
148+
}
149+
.into(),
150+
CallInstruction {
151+
span: Span::MISSING,
152+
dest_info: Some(InsnDestInfo {
153+
span: Span::MISSING,
154+
ty: BaseType::Single,
155+
dest: TemporaryName::unspanned("r"),
156+
}),
157+
target: Value::Constant(Constant::SymbolRef(GlobalName::unspanned("vadd"))),
158+
call_kw_span: Span::MISSING,
159+
args: vec![
160+
CallArgument::Regular(RegularCallArgument {
161+
ty: BaseType::Single.into(),
162+
value: TemporaryName::unspanned("a").into(),
163+
span: Span::MISSING,
164+
}),
165+
CallArgument::Regular(RegularCallArgument {
166+
ty: BaseType::Long.into(),
167+
value: TemporaryName::unspanned("ap").into(),
168+
span: Span::MISSING,
169+
}),
170+
],
171+
}
172+
.into(),
142173
],
143174
terminator: Some(JumpInstruction::Return {
144175
value: Some(TemporaryName::unspanned("r").into()),

src/lexer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ fn token<'a>() -> impl StringParser<'a, Token> {
107107
// must come after Operator since `z` is an operator
108108
ident().map(Token::Ident),
109109
string_literal().map(Token::StringLiteral),
110-
delimiter(),
111110
one_of("+-")
112111
.or_not()
113112
.ignore_then(text::int(10))
@@ -133,6 +132,7 @@ fn token<'a>() -> impl StringParser<'a, Token> {
133132
.map(Token::from);
134133
let newline_token = ascii_newline().repeated().at_least(1).to(Token::Newline);
135134
symbol
135+
.or(delimiter())
136136
.or(basic_token.then_ignore(require_space_like()))
137137
.or(newline_token)
138138
.labelled("token")

src/lexer/tokens.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ define_keyword_enum!(
301301
Align,
302302
Call,
303303
Data,
304+
Env,
304305
Export,
305306
Function,
306307
Hlt,

0 commit comments

Comments
 (0)