Skip to content

Commit 6636a8e

Browse files
authored
Merge pull request #71 from ExpHP/zero-zero
a couple of easy things pulled out from zero's PR
2 parents 0f32abf + b763d1c commit 6636a8e

File tree

16 files changed

+188
-56
lines changed

16 files changed

+188
-56
lines changed

build/gen_macros.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ pub fn gen_ast_macros() -> String {
9999
"expr_unop", &[
100100
("op", ArgKind::Token(&[
101101
"-", "!",
102-
"sin", "cos", "sqrt",
102+
"sin", "cos", "tan",
103+
"asin", "acos", "atan",
104+
"sqrt",
103105
"_S", "_f", // $ has to be written as _S since it's a macro meta-char
104106
"%", "int", "float",
105107
])),

doc/syntax.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ Literals can be:
4141

4242
* **Integers:** `123`, `0x123`, `-0b00101`, `true`, `false`. There is no octal syntax. Literal numbers have no optional leading plus.
4343
* **Floats:** `1.0`, `-1.3f`, `2f`. Again, no leading plus.
44-
* **Strings:** `"The quick brown fox\njumped over the lazy dog"`. The control characters for strings are `\0`, `\n`, `\r`, `\\`, and `\"`.
44+
* **Strings:** `"The quick brown fox\njumped over the lazy dog"`. The control characters for strings are `\0`, `\n`, `\r`, `\\`, and `\"`.
4545

46-
Source text files for `truth` **must** be encoded in UTF-8. `truth` handles the conversion between the Shift-JIS encoding used in the binary files and the UTF-8 encoding used in source text. (in the future, you may even be able to configure which encoding is used in the binary files... but source text will always be UTF-8!)
46+
Source text files for `truth` **must** be encoded in UTF-8. `truth` handles the conversion between the Shift-JIS encoding used in the binary files and the UTF-8 encoding used in source text. (in the future, you may even be able to configure which encoding is used in the binary files... but source text will always be UTF-8!)
4747

4848
### Variables
4949

@@ -139,12 +139,12 @@ Other things present in expressions:
139139
140140
* The **ternary operator** `a ? b : c`. Right associative, [the way it should be](https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/#operators).
141141
* **Unary negation** `-x`.
142-
* **Special functions** `sin(x)` and `cos(x)`.
142+
* **Special functions** `sin(x)` and `cos(x)`. Some languages support `acos`, `asin`, `tan`, and `sqrt`.
143143
* **Logical right shift `>>>`**.
144144
* All ints in truth are signed so `>>` is an arithmetic right shift (sign-extended) for consistency.
145145
`>>>` is provided as a separate operator for doing logical right shifts (zero-extended).
146146
* **Explicit casts** `_S` (float to int) and `_f` (int to float): `I0 = _S(F0);`
147-
* That example is identical to `I0 = $F0`, but `_S` is also more generally usable in larger expressions where it may introduce a temporary
147+
* That example is identical to `I0 = $F0`, but `_S` is also more generally usable in larger expressions where it may introduce a temporary
148148
149149
### Assignments
150150
@@ -217,7 +217,7 @@ times(I2 = I0) {
217217
```
218218
219219
#### About conditions
220-
220+
221221
In the desugared form of `times()` above, you'll notice that there is a `while (--var)`. This `--var` is not an expression!
222222
223223
Basically, a **condition** can either be an expression `<expr>` or a predecrement operation `--<var>`. The latter compiles to a special kind of jump available in ANM and early ECL that decrements a variable and jumps if it is nonzero. (*every single `while` loop in vanilla ANM files uses this form of jump,* so the ability to decompile it seemed... kind of important!)
@@ -290,7 +290,7 @@ Notice that, unlike conditional blocks, *the conditional jump has no braces*; it
290290
```C
291291
// this compiles to a single instruction in anm
292292
if (I0 != 0) goto else_label;
293-
293+
294294
// this typically compiles to more than one instruction
295295
if (I0 != 0) {
296296
goto else_label;
@@ -317,7 +317,7 @@ However, this is generally obsolete. Normally, the only reason the game ever us
317317
label: // has time label 15
318318
bar()
319319
goto label @ 10;
320-
320+
321321

322322
// is equivalent to
323323
10:

map/v2.anmm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
61 fsin
7272
62 fcos
7373
63 ftan
74-
64 acos
74+
64 facos
7575
65 fatan
7676
66 validRad
7777

src/ast/meta.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,10 @@ impl ToMeta for f32 {
576576
fn to_meta(&self) -> Meta { Meta::Scalar(sp!((*self).into())) }
577577
}
578578
impl ToMeta for bool {
579-
fn to_meta(&self) -> Meta { Meta::Scalar(sp!(ast::Expr::LitInt { value: *self as i32, radix: ast::IntRadix::Bool })) }
579+
fn to_meta(&self) -> Meta { Meta::Scalar(sp!(ast::Expr::LitInt {
580+
value: *self as i32,
581+
format: ast::IntFormat::BOOL,
582+
}))}
580583
}
581584
impl ToMeta for String {
582585
fn to_meta(&self) -> Meta { Meta::Scalar(sp!(self.to_owned().into())) }

src/ast/mod.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,8 @@ pub enum Expr {
454454
LitInt {
455455
value: raw::LangInt,
456456
/// A hint to the formatter on how it should write the integer.
457-
/// (may not necessarily represent the original radix of a parsed token)
458-
radix: IntRadix,
457+
/// (not meaningful when parsing)
458+
format: IntFormat,
459459
},
460460
LitFloat { value: raw::LangFloat },
461461
LitString(LitString),
@@ -469,14 +469,29 @@ pub enum Expr {
469469
},
470470
}
471471

472+
473+
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
474+
pub struct IntFormat {
475+
pub signed: bool,
476+
pub radix: IntRadix,
477+
}
478+
479+
impl IntFormat {
480+
pub const UNSIGNED: IntFormat = IntFormat { signed: false, radix: IntRadix::Dec };
481+
pub const SIGNED: IntFormat = IntFormat { signed: true, radix: IntRadix::Dec };
482+
pub const HEX: IntFormat = IntFormat { signed: false, radix: IntRadix::Hex };
483+
pub const BIN: IntFormat = IntFormat { signed: false, radix: IntRadix::Bin };
484+
pub const BOOL: IntFormat = IntFormat { signed: true, radix: IntRadix::Bool };
485+
/// Used to decompile `jmp` in function syntax.
486+
pub const SIGNED_HEX: IntFormat = IntFormat { signed: true, radix: IntRadix::Hex };
487+
}
488+
472489
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
473490
pub enum IntRadix {
474491
/// Display as decimal.
475492
Dec,
476493
/// Display as hexadecimal, with an `0x` prefix.
477494
Hex,
478-
/// Display as potentially negative hexadecimal, with an `0x` prefix.
479-
SignedHex,
480495
/// Display as binary, with an `0b` prefix.
481496
Bin,
482497
/// Use `true` and `false` if the value is `1` or `0`. Otherwise, fall back to decimal.
@@ -695,6 +710,10 @@ string_enum! {
695710
#[strum(serialize = "~")] BitNot,
696711
#[strum(serialize = "sin")] Sin,
697712
#[strum(serialize = "cos")] Cos,
713+
#[strum(serialize = "tan")] Tan,
714+
#[strum(serialize = "asin")] Asin,
715+
#[strum(serialize = "acos")] Acos,
716+
#[strum(serialize = "atan")] Atan,
698717
#[strum(serialize = "sqrt")] Sqrt,
699718
#[strum(serialize = "$")] EncodeI,
700719
#[strum(serialize = "%")] EncodeF,
@@ -711,6 +730,10 @@ impl UnOpKind {
711730
UnOpKind::BitNot => OpClass::Bitwise,
712731
UnOpKind::Sin => OpClass::FloatMath,
713732
UnOpKind::Cos => OpClass::FloatMath,
733+
UnOpKind::Tan => OpClass::FloatMath,
734+
UnOpKind::Asin => OpClass::FloatMath,
735+
UnOpKind::Acos => OpClass::FloatMath,
736+
UnOpKind::Atan => OpClass::FloatMath,
714737
UnOpKind::Sqrt => OpClass::FloatMath,
715738
UnOpKind::CastI => OpClass::Cast,
716739
UnOpKind::CastF => OpClass::Cast,
@@ -842,7 +865,7 @@ string_enum! {
842865
}
843866

844867
impl From<raw::LangInt> for Expr {
845-
fn from(value: raw::LangInt) -> Expr { Expr::LitInt { value, radix: IntRadix::Dec } }
868+
fn from(value: raw::LangInt) -> Expr { Expr::LitInt { value, format: IntFormat::SIGNED } }
846869
}
847870
impl From<raw::LangFloat> for Expr {
848871
fn from(value: raw::LangFloat) -> Expr { Expr::LitFloat { value } }
@@ -1261,7 +1284,7 @@ macro_rules! generate_visitor_stuff {
12611284
Expr::XcrementOp { op: _, order: _, var } => {
12621285
v.visit_var(var);
12631286
},
1264-
Expr::LitInt { value: _, radix: _ } => {},
1287+
Expr::LitInt { value: _, format: _ } => {},
12651288
Expr::LitFloat { value: _ } => {},
12661289
Expr::LitString(_s) => {},
12671290
Expr::LabelProperty { .. } => {},

src/core_mapfiles/anm.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,9 @@ static ANM_INS_07_09: &'static CoreSignatures = &CoreSignatures {
150150
(Th07, 60, Some(("ff", None))),
151151
(Th07, 61, Some(("ff", Some(IKind::UnOp(U::Sin, Ty::Float))))),
152152
(Th07, 62, Some(("ff", Some(IKind::UnOp(U::Cos, Ty::Float))))),
153-
(Th07, 63, Some(("ff", None))),
154-
(Th07, 64, Some(("ff", None))),
155-
(Th07, 65, Some(("ff", None))),
153+
(Th07, 63, Some(("ff", Some(IKind::UnOp(U::Tan, Ty::Float))))),
154+
(Th07, 64, Some(("ff", Some(IKind::UnOp(U::Acos, Ty::Float))))),
155+
(Th07, 65, Some(("ff", Some(IKind::UnOp(U::Atan, Ty::Float))))),
156156
(Th07, 66, Some(("f", None))),
157157
(Th07, 67, Some(("SSot", Some(IKind::CondJmp(B::Eq, Ty::Int))))),
158158
(Th07, 68, Some(("ffot", Some(IKind::CondJmp(B::Eq, Ty::Float))))),
@@ -235,9 +235,9 @@ static ANM_INS_095_128: &'static CoreSignatures = &CoreSignatures {
235235
(Th095, 41, Some(("ff", None))),
236236
(Th095, 42, Some(("ff", Some(IKind::UnOp(U::Sin, Ty::Float))))),
237237
(Th095, 43, Some(("ff", Some(IKind::UnOp(U::Cos, Ty::Float))))),
238-
(Th095, 44, Some(("ff", None))),
239-
(Th095, 45, Some(("ff", None))),
240-
(Th095, 46, Some(("ff", None))),
238+
(Th095, 44, Some(("ff", Some(IKind::UnOp(U::Tan, Ty::Float))))),
239+
(Th095, 45, Some(("ff", Some(IKind::UnOp(U::Acos, Ty::Float))))),
240+
(Th095, 46, Some(("ff", Some(IKind::UnOp(U::Atan, Ty::Float))))),
241241
(Th095, 47, Some(("f", None))),
242242
(Th095, 48, Some(("fff", None))),
243243
(Th095, 49, Some(("fff", None))),
@@ -353,9 +353,9 @@ static ANM_INS_13_185: &CoreSignatures = &CoreSignatures {
353353
(Th13, 123, Some(("ff", None))),
354354
(Th13, 124, Some(("ff", Some(IKind::UnOp(U::Sin, Ty::Float))))),
355355
(Th13, 125, Some(("ff", Some(IKind::UnOp(U::Cos, Ty::Float))))),
356-
(Th13, 126, Some(("ff", None))),
357-
(Th13, 127, Some(("ff", None))),
358-
(Th13, 128, Some(("ff", None))),
356+
(Th13, 126, Some(("ff", Some(IKind::UnOp(U::Tan, Ty::Float))))),
357+
(Th13, 127, Some(("ff", Some(IKind::UnOp(U::Acos, Ty::Float))))),
358+
(Th13, 128, Some(("ff", Some(IKind::UnOp(U::Atan, Ty::Float))))),
359359
(Th13, 129, Some(("f", None))),
360360
(Th13, 130, Some(("ffff", None))),
361361
(Th13, 131, Some(("ffff", None))),

src/fmt.rs

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -886,24 +886,49 @@ impl Format for ast::Expr {
886886
})
887887
},
888888
ast::Expr::UnOp(op, x) => match op.value {
889-
token![unop -] | token![!] | token![~]
889+
| token![unop -] | token![!] | token![~]
890890
=> out.fmt_optional_parens(|out| out.fmt((op, x))),
891891

892-
token![unop $] | token![unop %] |
893-
token![unop int] | token![unop float] |
894-
token![sin] | token![cos] | token![sqrt]
892+
| token![unop $] | token![unop %]
893+
| token![unop int] | token![unop float]
894+
| token![sin] | token![cos] | token![tan]
895+
| token![asin] | token![acos] | token![atan]
896+
| token![sqrt]
895897
=> out.fmt((op, "(", SuppressParens(x), ")")),
896898
},
897899
ast::Expr::XcrementOp { order: ast::XcrementOpOrder::Pre, op, var } => out.fmt((op, var)),
898900
ast::Expr::XcrementOp { order: ast::XcrementOpOrder::Post, op, var } => out.fmt((var, op)),
899901
ast::Expr::EnumConst { enum_name, ident } => out.fmt((enum_name, ".", ident)),
900-
ast::Expr::LitInt { value: 0, radix: ast::IntRadix::Bool } => out.fmt("false"),
901-
ast::Expr::LitInt { value: 1, radix: ast::IntRadix::Bool } => out.fmt("true"),
902-
ast::Expr::LitInt { value, radix: ast::IntRadix::Bool } => out.fmt(value),
903-
ast::Expr::LitInt { value, radix: ast::IntRadix::Dec } => out.fmt(value),
904-
ast::Expr::LitInt { value, radix: ast::IntRadix::Hex } => out.fmt(format_args!("{:#x}", value)),
905-
ast::Expr::LitInt { value, radix: ast::IntRadix::SignedHex } => out.fmt(format_args!("{:#x}", SignedRadix(*value))),
906-
ast::Expr::LitInt { value, radix: ast::IntRadix::Bin } => out.fmt(format_args!("{:#b}", value)),
902+
ast::Expr::LitInt { value, format } => match format {
903+
// These are the decimal formats
904+
&ast::IntFormat::SIGNED => out.fmt(value),
905+
&ast::IntFormat::UNSIGNED => {
906+
out.fmt(format_args!("{}", *value as u32))
907+
},
908+
909+
&ast::IntFormat { radix: ast::IntRadix::Hex, signed } => {
910+
match signed {
911+
false => out.fmt(format_args!("{:#x}", value)),
912+
true => out.fmt(format_args!("{:#x}", SignedRadix(*value))),
913+
}
914+
},
915+
916+
&ast::IntFormat { radix: ast::IntRadix::Bin, signed } => {
917+
match signed {
918+
false => out.fmt(format_args!("{:#b}", value)),
919+
true => out.fmt(format_args!("{:#b}", SignedRadix(*value))),
920+
}
921+
},
922+
923+
&ast::IntFormat { radix: ast::IntRadix::Bool, signed } => {
924+
match (value, signed) {
925+
(0, _) => out.fmt("false"),
926+
(1, _) => out.fmt("true"),
927+
(_, true) => out.fmt(value),
928+
(_, false) => out.fmt(format_args!("{:#x}", *value as u32)),
929+
}
930+
},
931+
},
907932
ast::Expr::LitFloat { value } => out.fmt(value),
908933
ast::Expr::LitString(x) => out.fmt(x),
909934
ast::Expr::LabelProperty { label, keyword } => out.fmt((keyword, "(", label, ")")),
@@ -1134,4 +1159,32 @@ mod tests {
11341159
assert!(reformat::<ast::ScriptFile>(3, r#"meta { x: 25 }"#).ends_with("\n"));
11351160
assert!(reformat::<ast::ScriptFile>(9999, r#" script lol { nop(); }"#).ends_with("\n"));
11361161
}
1162+
1163+
#[test]
1164+
fn integer_formats() {
1165+
use ast::IntRadix as R;
1166+
1167+
fn fmt_int(value: i32, signed: bool, radix: R) -> String {
1168+
stringify(&ast::Expr::LitInt {
1169+
value,
1170+
format: ast::IntFormat { signed, radix }
1171+
})
1172+
}
1173+
1174+
assert_eq!(fmt_int(20, true, R::Dec), "20");
1175+
assert_eq!(fmt_int(-20, true, R::Dec), "-20");
1176+
assert_eq!(fmt_int(-0x30, true, R::Hex), "-0x30");
1177+
assert_eq!(fmt_int(-0x30, false, R::Hex), "0xffffffd0");
1178+
assert_eq!(fmt_int(-0b100, true, R::Bin), "-0b100");
1179+
1180+
assert_eq!(fmt_int(0, true, R::Bool), "false");
1181+
assert_eq!(fmt_int(0, false, R::Bool), "false");
1182+
assert_eq!(fmt_int(1, true, R::Bool), "true");
1183+
assert_eq!(fmt_int(1, false, R::Bool), "true");
1184+
assert_eq!(fmt_int(2, true, R::Bool), "2");
1185+
assert_eq!(fmt_int(2, false, R::Bool), "0x2");
1186+
assert_eq!(fmt_int(-2, true, R::Bool), "-2");
1187+
assert_eq!(fmt_int(-2, false, R::Bool), "0xfffffffe");
1188+
}
11371189
}
1190+

src/formats/anm/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ fn format_to_meta(format_num: u32) -> Meta {
686686
}
687687

688688
fn colorkey_to_meta(colorkey: u32) -> impl ToMeta {
689-
ast::Expr::LitInt { value: colorkey as i32, radix: ast::IntRadix::Hex }
689+
ast::Expr::LitInt { value: colorkey as i32, format: ast::IntFormat::HEX }
690690
}
691691

692692
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]

0 commit comments

Comments
 (0)