parser.rs 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207
  1. use {
  2. crate::{
  3. ast::AST,
  4. astnode::{ASTNode, Directive, EquDecl, ExternDecl, GlobalDecl, Label, ROData, RodataDecl},
  5. bug,
  6. dynsym::{DynamicSymbolMap, RelDynMap},
  7. errors::CompileError,
  8. instruction::Instruction,
  9. lexer::{ImmediateValue, Op, Token},
  10. messages::*,
  11. section::{CodeSection, DataSection},
  12. },
  13. num_traits::FromPrimitive,
  14. sbpf_common::opcode::Opcode,
  15. std::collections::HashMap,
  16. };
  17. pub struct ParseResult {
  18. // TODO: parse result is basically 1. static part 2. dynamic part of the program
  19. pub code_section: CodeSection,
  20. pub data_section: DataSection,
  21. pub dynamic_symbols: DynamicSymbolMap,
  22. pub relocation_data: RelDynMap,
  23. // TODO: this can be removed and dynamic-ness should just be
  24. // determined by if there's any dynamic symbol
  25. pub prog_is_static: bool,
  26. }
  27. // for now, we only return one error per parse for simpler error handling
  28. pub trait Parse {
  29. fn parse(tokens: &[Token]) -> Result<(Self, &[Token]), CompileError>
  30. where
  31. Self: Sized;
  32. }
  33. pub trait ParseWithConstMap {
  34. fn parse_with_constmap<'a>(
  35. tokens: &'a [Token],
  36. const_map: &HashMap<String, ImmediateValue>,
  37. ) -> Result<(Self, &'a [Token]), CompileError>
  38. where
  39. Self: Sized;
  40. }
  41. impl Parse for GlobalDecl {
  42. fn parse(tokens: &[Token]) -> Result<(Self, &[Token]), CompileError> {
  43. let Token::Directive(_, span) = &tokens[0] else {
  44. bug!("GlobalDecl not a valid directive")
  45. };
  46. if tokens.len() < 2 {
  47. return Err(CompileError::InvalidGlobalDecl {
  48. span: span.clone(),
  49. custom_label: None,
  50. });
  51. }
  52. match &tokens[1] {
  53. Token::Identifier(name, span) => Ok((
  54. GlobalDecl {
  55. entry_label: name.clone(),
  56. span: span.clone(),
  57. },
  58. &tokens[2..],
  59. )),
  60. _ => Err(CompileError::InvalidGlobalDecl {
  61. span: span.clone(),
  62. custom_label: None,
  63. }),
  64. }
  65. }
  66. }
  67. impl ParseWithConstMap for EquDecl {
  68. fn parse_with_constmap<'a>(
  69. tokens: &'a [Token],
  70. const_map: &HashMap<String, ImmediateValue>,
  71. ) -> Result<(Self, &'a [Token]), CompileError> {
  72. let Token::Directive(_, span) = &tokens[0] else {
  73. bug!("EquDecl not a valid directive")
  74. };
  75. if tokens.len() < 3 {
  76. return Err(CompileError::InvalidEquDecl {
  77. span: span.clone(),
  78. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  79. });
  80. }
  81. let (value, advance_token_num) = inline_and_fold_constant(tokens, const_map, 3);
  82. if let Some(value) = value {
  83. match (
  84. &tokens[1], &tokens[2],
  85. // third operand is folded to an immediate value
  86. ) {
  87. (
  88. Token::Identifier(name, span),
  89. Token::Comma(_),
  90. // third operand is folded to an immediate value
  91. ) => Ok((
  92. EquDecl {
  93. name: name.clone(),
  94. value: Token::ImmediateValue(value, span.clone()),
  95. span: span.clone(),
  96. },
  97. &tokens[advance_token_num..],
  98. )),
  99. _ => Err(CompileError::InvalidEquDecl {
  100. span: span.clone(),
  101. custom_label: Some(EXPECTS_IDEN_COM_IMM.to_string()),
  102. }),
  103. }
  104. } else {
  105. Err(CompileError::InvalidEquDecl {
  106. span: span.clone(),
  107. custom_label: Some(EXPECTS_IDEN_COM_IMM.to_string()),
  108. })
  109. }
  110. }
  111. }
  112. impl Parse for ExternDecl {
  113. fn parse(tokens: &[Token]) -> Result<(Self, &[Token]), CompileError> {
  114. let Token::Directive(_, span) = &tokens[0] else {
  115. bug!("ExternDecl not a valid directive")
  116. };
  117. if tokens.len() < 2 {
  118. return Err(CompileError::InvalidExternDecl {
  119. span: span.clone(),
  120. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  121. });
  122. }
  123. let mut args = Vec::new();
  124. let mut i = 1;
  125. while i < tokens.len() {
  126. match &tokens[i] {
  127. Token::Identifier(name, span) => {
  128. args.push(Token::Identifier(name.clone(), span.clone()));
  129. i += 1;
  130. }
  131. _ => {
  132. break;
  133. }
  134. }
  135. }
  136. //
  137. if args.is_empty() {
  138. Err(CompileError::InvalidExternDecl {
  139. span: span.clone(),
  140. custom_label: Some(EXPECTS_IDEN.to_string()),
  141. })
  142. } else {
  143. Ok((
  144. ExternDecl {
  145. args,
  146. span: span.clone(),
  147. },
  148. &tokens[i..],
  149. ))
  150. }
  151. }
  152. }
  153. impl Parse for ROData {
  154. fn parse(tokens: &[Token]) -> Result<(Self, &[Token]), CompileError> {
  155. let Token::Label(_, span) = &tokens[0] else {
  156. bug!("ROData not a valid directive")
  157. };
  158. if tokens.len() < 3 {
  159. return Err(CompileError::InvalidRodataDecl {
  160. span: span.clone(),
  161. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  162. });
  163. }
  164. let mut args = Vec::new();
  165. match (&tokens[0], &tokens[1], &tokens[2]) {
  166. (Token::Label(name, span), Token::Directive(_, _), Token::StringLiteral(_, _)) => {
  167. args.push(tokens[1].clone());
  168. args.push(tokens[2].clone());
  169. Ok((
  170. ROData {
  171. name: name.clone(),
  172. args,
  173. span: span.clone(),
  174. },
  175. &tokens[3..],
  176. ))
  177. }
  178. (Token::Label(name, span), Token::Directive(_, _), Token::ImmediateValue(val, _)) => {
  179. let mut data_vector = vec![val.clone()];
  180. let idx = parse_vector_literal(tokens, &mut data_vector, 3);
  181. args.push(tokens[1].clone());
  182. args.push(Token::VectorLiteral(data_vector, span.clone()));
  183. Ok((
  184. ROData {
  185. name: name.clone(),
  186. args,
  187. span: span.clone(),
  188. },
  189. &tokens[idx..],
  190. ))
  191. }
  192. _ => Err(CompileError::InvalidRodataDecl {
  193. span: span.clone(),
  194. custom_label: Some(EXPECTS_LABEL_DIR_STR.to_string()),
  195. }),
  196. }
  197. }
  198. }
  199. impl ParseWithConstMap for Instruction {
  200. fn parse_with_constmap<'a>(
  201. tokens: &'a [Token],
  202. const_map: &HashMap<String, ImmediateValue>,
  203. ) -> Result<(Self, &'a [Token]), CompileError> {
  204. let next_token_num;
  205. match &tokens[0] {
  206. Token::Opcode(opcode, span) => {
  207. let mut opcode = *opcode;
  208. let mut operands = Vec::new();
  209. match opcode {
  210. Opcode::Lddw => {
  211. if tokens.len() < 4 {
  212. return Err(CompileError::InvalidInstruction {
  213. //
  214. instruction: opcode.to_string(), //
  215. span: span.clone(), //
  216. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  217. });
  218. }
  219. let (value, advance_token_num) =
  220. inline_and_fold_constant(tokens, const_map, 3);
  221. if let Some(value) = value {
  222. match (
  223. &tokens[1],
  224. &tokens[2],
  225. // Third operand is folded to an immediate value
  226. ) {
  227. (
  228. Token::Register(_, _),
  229. Token::Comma(_),
  230. // Third operand is folded to an immediate value
  231. ) => {
  232. operands.push(tokens[1].clone());
  233. operands.push(Token::ImmediateValue(value, span.clone()));
  234. }
  235. _ => {
  236. return Err(CompileError::InvalidInstruction {
  237. //
  238. instruction: opcode.to_string(), //
  239. span: span.clone(), //
  240. custom_label: Some(EXPECTS_REG_COM_IMM_OR_IDEN.to_string()),
  241. });
  242. }
  243. }
  244. next_token_num = advance_token_num;
  245. } else {
  246. match (&tokens[1], &tokens[2], &tokens[3]) {
  247. (
  248. Token::Register(_, _),
  249. Token::Comma(_),
  250. Token::Identifier(_, _),
  251. ) => {
  252. operands.push(tokens[1].clone());
  253. operands.push(tokens[3].clone());
  254. }
  255. _ => {
  256. return Err(CompileError::InvalidInstruction {
  257. //
  258. instruction: opcode.to_string(), //
  259. span: span.clone(), //
  260. custom_label: Some(EXPECTS_REG_COM_IMM_OR_IDEN.to_string()),
  261. });
  262. }
  263. }
  264. next_token_num = 4;
  265. }
  266. }
  267. Opcode::Ldxw | Opcode::Ldxh | Opcode::Ldxb | Opcode::Ldxdw => {
  268. if tokens.len() < 8 {
  269. return Err(CompileError::InvalidInstruction {
  270. //
  271. instruction: opcode.to_string(), //
  272. span: span.clone(), //
  273. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  274. });
  275. }
  276. let (value, advance_token_num) =
  277. inline_and_fold_constant(tokens, const_map, 6);
  278. if let Some(value) = value {
  279. match (
  280. &tokens[1],
  281. &tokens[2],
  282. &tokens[3],
  283. &tokens[4],
  284. &tokens[5],
  285. // Sixth operand is folded to an immediate value
  286. &tokens[advance_token_num],
  287. ) {
  288. (
  289. Token::Register(_, _),
  290. Token::Comma(_),
  291. Token::LeftBracket(_),
  292. Token::Register(_, _),
  293. Token::BinaryOp(_, _),
  294. // Sixth operand is folded to an immediate value
  295. Token::RightBracket(_),
  296. ) => {
  297. operands.push(tokens[1].clone());
  298. operands.push(tokens[4].clone());
  299. operands.push(Token::ImmediateValue(value, span.clone()));
  300. }
  301. _ => {
  302. return Err(CompileError::InvalidInstruction {
  303. //
  304. instruction: opcode.to_string(), //
  305. span: span.clone(), //
  306. custom_label: Some(
  307. EXPECTS_REG_COM_LB_REG_BIOP_IMM_RB.to_string(),
  308. ),
  309. });
  310. }
  311. }
  312. next_token_num = advance_token_num + 1;
  313. } else {
  314. return Err(CompileError::InvalidInstruction {
  315. //
  316. instruction: opcode.to_string(), //
  317. span: span.clone(), //
  318. custom_label: Some(EXPECTS_REG_COM_LB_REG_BIOP_IMM_RB.to_string()),
  319. });
  320. }
  321. }
  322. Opcode::Stw | Opcode::Sth | Opcode::Stb | Opcode::Stdw => {
  323. if tokens.len() < 8 {
  324. return Err(CompileError::InvalidInstruction {
  325. //
  326. instruction: opcode.to_string(), //
  327. span: span.clone(), //
  328. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  329. });
  330. }
  331. let (value, advance_token_num) =
  332. inline_and_fold_constant(tokens, const_map, 4);
  333. if let Some(value) = value {
  334. // Now we need to fold the second immediate value (after the comma)
  335. let (value2, advance_token_num2) =
  336. inline_and_fold_constant(tokens, const_map, advance_token_num + 2);
  337. if let Some(value2) = value2 {
  338. match (
  339. &tokens[1],
  340. &tokens[2],
  341. &tokens[3],
  342. // Fourth operand is folded to an immediate value
  343. &tokens[advance_token_num],
  344. &tokens[advance_token_num + 1],
  345. // Sixth operand is also folded to an immediate value
  346. ) {
  347. (
  348. Token::LeftBracket(_),
  349. Token::Register(_, _),
  350. Token::BinaryOp(_, _),
  351. // Fourth operand is folded to an immediate value
  352. Token::RightBracket(_),
  353. Token::Comma(_),
  354. ) => {
  355. operands.push(tokens[2].clone());
  356. operands.push(Token::ImmediateValue(value2, span.clone()));
  357. operands.push(Token::ImmediateValue(value, span.clone()));
  358. }
  359. _ => {
  360. return Err(CompileError::InvalidInstruction {
  361. //
  362. instruction: opcode.to_string(), //
  363. span: span.clone(), //
  364. custom_label: Some(
  365. EXPECTS_LB_REG_BIOP_IMM_RB_COM_IMM.to_string(),
  366. ),
  367. });
  368. }
  369. }
  370. next_token_num = advance_token_num2;
  371. } else {
  372. return Err(CompileError::InvalidInstruction {
  373. //
  374. instruction: opcode.to_string(), //
  375. span: span.clone(), //
  376. custom_label: Some(
  377. EXPECTS_LB_REG_BIOP_IMM_RB_COM_IMM.to_string(),
  378. ),
  379. });
  380. }
  381. } else {
  382. return Err(CompileError::InvalidInstruction {
  383. //
  384. instruction: opcode.to_string(), //
  385. span: span.clone(), //
  386. custom_label: Some(EXPECTS_LB_REG_BIOP_IMM_RB_COM_IMM.to_string()),
  387. });
  388. }
  389. }
  390. Opcode::Stxb | Opcode::Stxh | Opcode::Stxw | Opcode::Stxdw => {
  391. if tokens.len() < 8 {
  392. return Err(CompileError::InvalidInstruction {
  393. //
  394. instruction: opcode.to_string(), //
  395. span: span.clone(), //
  396. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  397. });
  398. }
  399. let (value, advance_token_num) =
  400. inline_and_fold_constant(tokens, const_map, 4);
  401. if let Some(value) = value {
  402. match (
  403. &tokens[1],
  404. &tokens[2],
  405. &tokens[3],
  406. // Fourth operand is folded to an immediate value
  407. &tokens[advance_token_num],
  408. &tokens[advance_token_num + 1],
  409. &tokens[advance_token_num + 2],
  410. ) {
  411. (
  412. Token::LeftBracket(_),
  413. Token::Register(_, _),
  414. Token::BinaryOp(_, _),
  415. // Fourth operand is folded to an immediate value
  416. Token::RightBracket(_),
  417. Token::Comma(_),
  418. Token::Register(_, _),
  419. ) => {
  420. operands.push(tokens[2].clone());
  421. operands.push(Token::ImmediateValue(value, span.clone()));
  422. operands.push(tokens[advance_token_num + 2].clone());
  423. }
  424. _ => {
  425. return Err(CompileError::InvalidInstruction {
  426. //
  427. instruction: opcode.to_string(), //
  428. span: span.clone(), //
  429. custom_label: Some(
  430. EXPECTS_LB_REG_BIOP_IMM_RB_COM_REG.to_string(),
  431. ),
  432. });
  433. }
  434. }
  435. next_token_num = advance_token_num + 3;
  436. } else {
  437. return Err(CompileError::InvalidInstruction {
  438. //
  439. instruction: opcode.to_string(), //
  440. span: span.clone(), //
  441. custom_label: Some(EXPECTS_LB_REG_BIOP_IMM_RB_COM_REG.to_string()),
  442. });
  443. }
  444. }
  445. Opcode::Add32
  446. | Opcode::Sub32
  447. | Opcode::Mul32
  448. | Opcode::Div32
  449. | Opcode::Or32
  450. | Opcode::And32
  451. | Opcode::Lsh32
  452. | Opcode::Rsh32
  453. | Opcode::Mod32
  454. | Opcode::Xor32
  455. | Opcode::Mov32
  456. | Opcode::Arsh32
  457. | Opcode::Lmul32
  458. | Opcode::Udiv32
  459. | Opcode::Urem32
  460. | Opcode::Sdiv32
  461. | Opcode::Srem32
  462. | Opcode::Add64
  463. | Opcode::Sub64
  464. | Opcode::Mul64
  465. | Opcode::Div64
  466. | Opcode::Or64
  467. | Opcode::And64
  468. | Opcode::Lsh64
  469. | Opcode::Rsh64
  470. | Opcode::Mod64
  471. | Opcode::Xor64
  472. | Opcode::Mov64
  473. | Opcode::Arsh64
  474. | Opcode::Lmul64
  475. | Opcode::Uhmul64
  476. | Opcode::Udiv64
  477. | Opcode::Urem64
  478. | Opcode::Sdiv64
  479. | Opcode::Srem64 => {
  480. if tokens.len() < 4 {
  481. return Err(CompileError::InvalidInstruction {
  482. //
  483. instruction: opcode.to_string(), //
  484. span: span.clone(), //
  485. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  486. });
  487. }
  488. let (value, advance_token_num) =
  489. inline_and_fold_constant(tokens, const_map, 3);
  490. if let Some(value) = value {
  491. match (
  492. &tokens[1],
  493. &tokens[2],
  494. // Third operand is folded to an immediate value
  495. ) {
  496. (
  497. Token::Register(_, _),
  498. Token::Comma(_),
  499. // Third operand is folded to an immediate value
  500. ) => {
  501. opcode = FromPrimitive::from_u8((opcode as u8) + 1)
  502. .expect("Invalid opcode conversion");
  503. operands.push(tokens[1].clone());
  504. operands.push(Token::ImmediateValue(value, span.clone()));
  505. }
  506. _ => {
  507. return Err(CompileError::InvalidInstruction {
  508. //
  509. instruction: opcode.to_string(), //
  510. span: span.clone(), //
  511. custom_label: Some(EXPECTS_REG_COM_IMM.to_string()),
  512. });
  513. }
  514. }
  515. next_token_num = advance_token_num;
  516. } else {
  517. match (&tokens[1], &tokens[2], &tokens[3]) {
  518. (Token::Register(_, _), Token::Comma(_), Token::Register(_, _)) => {
  519. opcode = FromPrimitive::from_u8((opcode as u8) + 2)
  520. .expect("Invalid opcode conversion");
  521. operands.push(tokens[1].clone());
  522. operands.push(tokens[3].clone());
  523. }
  524. _ => {
  525. return Err(CompileError::InvalidInstruction {
  526. //
  527. instruction: opcode.to_string(), //
  528. span: span.clone(), //
  529. custom_label: Some(EXPECTS_REG_COM_REG.to_string()),
  530. });
  531. }
  532. }
  533. next_token_num = 4;
  534. }
  535. }
  536. Opcode::Be | Opcode::Le => {
  537. if tokens.len() < 4 {
  538. return Err(CompileError::InvalidInstruction {
  539. //
  540. instruction: opcode.to_string(), //
  541. span: span.clone(), //
  542. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  543. });
  544. }
  545. let (value, advance_token_num) =
  546. inline_and_fold_constant(tokens, const_map, 3);
  547. if let Some(value) = value {
  548. match (
  549. &tokens[1],
  550. &tokens[2],
  551. // Third operand is folded to an immediate value
  552. ) {
  553. (
  554. Token::Register(_, _),
  555. Token::Comma(_),
  556. // Third operand is folded to an immediate value
  557. ) => {
  558. operands.push(tokens[1].clone());
  559. operands.push(Token::ImmediateValue(value, span.clone()));
  560. }
  561. _ => {
  562. return Err(CompileError::InvalidInstruction {
  563. //
  564. instruction: opcode.to_string(), //
  565. span: span.clone(), //
  566. custom_label: Some(EXPECTS_REG_COM_IMM.to_string()),
  567. });
  568. }
  569. }
  570. next_token_num = advance_token_num;
  571. } else {
  572. return Err(CompileError::InvalidInstruction {
  573. //
  574. instruction: opcode.to_string(), //
  575. span: span.clone(), //
  576. custom_label: Some(EXPECTS_REG_COM_IMM.to_string()),
  577. });
  578. }
  579. }
  580. Opcode::Jeq
  581. | Opcode::Jgt
  582. | Opcode::Jge
  583. | Opcode::Jlt
  584. | Opcode::Jle
  585. | Opcode::Jset
  586. | Opcode::Jne
  587. | Opcode::Jsgt
  588. | Opcode::Jsge
  589. | Opcode::Jslt
  590. | Opcode::Jsle => {
  591. if tokens.len() < 6 {
  592. return Err(CompileError::InvalidInstruction {
  593. //
  594. instruction: opcode.to_string(), //
  595. span: span.clone(), //
  596. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  597. });
  598. }
  599. let (value, advance_token_num) =
  600. inline_and_fold_constant(tokens, const_map, 3);
  601. if let Some(value) = value {
  602. let (jump_val, jump_val_advance_token_num) =
  603. inline_and_fold_constant(tokens, const_map, advance_token_num + 1);
  604. if let Some(jump_val) = jump_val {
  605. match (
  606. &tokens[1],
  607. &tokens[2],
  608. // Third operand is folded to an immediate value
  609. &tokens[advance_token_num],
  610. // Fifth operand is folded to an immediate value
  611. ) {
  612. (
  613. Token::Register(_, _),
  614. Token::Comma(_),
  615. // Third operand is folded to an immediate value
  616. Token::Comma(_),
  617. // Fifth operand is folded to an immediate value
  618. ) => {
  619. opcode = FromPrimitive::from_u8((opcode as u8) + 1)
  620. .expect("Invalid opcode conversion");
  621. operands.push(tokens[1].clone());
  622. operands.push(Token::ImmediateValue(value, span.clone()));
  623. operands
  624. .push(Token::ImmediateValue(jump_val, span.clone()));
  625. }
  626. _ => {
  627. return Err(CompileError::InvalidInstruction {
  628. instruction: opcode.to_string(),
  629. span: span.clone(),
  630. custom_label: Some(
  631. EXPECTS_REG_COM_IMM_COM_IMM_OR_IDEN.to_string(),
  632. ),
  633. });
  634. }
  635. }
  636. next_token_num = jump_val_advance_token_num;
  637. } else {
  638. match (
  639. &tokens[1],
  640. &tokens[2],
  641. // Third operand is folded to an immediate value
  642. &tokens[advance_token_num],
  643. &tokens[advance_token_num + 1],
  644. ) {
  645. (
  646. Token::Register(_, _),
  647. Token::Comma(_),
  648. // Third operand is folded to an immediate value
  649. Token::Comma(_),
  650. Token::Identifier(_, _),
  651. ) => {
  652. opcode = FromPrimitive::from_u8((opcode as u8) + 1)
  653. .expect("Invalid opcode conversion");
  654. operands.push(tokens[1].clone());
  655. operands.push(Token::ImmediateValue(value, span.clone()));
  656. operands.push(tokens[advance_token_num + 1].clone());
  657. }
  658. _ => {
  659. return Err(CompileError::InvalidInstruction {
  660. //
  661. instruction: opcode.to_string(), //
  662. span: span.clone(), //
  663. custom_label: Some(
  664. EXPECTS_REG_COM_IMM_COM_IMM_OR_IDEN.to_string(),
  665. ),
  666. });
  667. }
  668. }
  669. next_token_num = advance_token_num + 2;
  670. }
  671. } else {
  672. let (jump_val, jump_val_advance_token_num) =
  673. inline_and_fold_constant(tokens, const_map, advance_token_num + 1);
  674. if let Some(jump_val) = jump_val {
  675. match (
  676. &tokens[1], &tokens[2], &tokens[3],
  677. &tokens[4],
  678. // Fifth operand is folded to an immediate value
  679. ) {
  680. (
  681. Token::Register(_, _),
  682. Token::Comma(_),
  683. Token::Register(_, _),
  684. Token::Comma(_),
  685. // Fifth operand is folded to an immediate value
  686. ) => {
  687. // turn "invalid opcode" to a bug
  688. opcode = FromPrimitive::from_u8((opcode as u8) + 2)
  689. .expect("Invalid opcode conversion");
  690. operands.push(tokens[1].clone());
  691. operands.push(tokens[3].clone());
  692. operands
  693. .push(Token::ImmediateValue(jump_val, span.clone()));
  694. }
  695. _ => {
  696. return Err(CompileError::InvalidInstruction {
  697. //
  698. instruction: opcode.to_string(), //
  699. span: span.clone(), //
  700. custom_label: Some(
  701. EXPECTS_REG_COM_IMM_COM_IMM_OR_IDEN.to_string(),
  702. ),
  703. });
  704. }
  705. }
  706. next_token_num = jump_val_advance_token_num;
  707. } else {
  708. match (&tokens[1], &tokens[2], &tokens[3], &tokens[4], &tokens[5]) {
  709. (
  710. Token::Register(_, _),
  711. Token::Comma(_),
  712. Token::Register(_, _),
  713. Token::Comma(_),
  714. Token::Identifier(_, _),
  715. ) => {
  716. // turn "invalid opcode" to a bug
  717. opcode = FromPrimitive::from_u8((opcode as u8) + 2)
  718. .expect("Invalid opcode conversion");
  719. operands.push(tokens[1].clone());
  720. operands.push(tokens[3].clone());
  721. operands.push(tokens[5].clone());
  722. }
  723. _ => {
  724. return Err(CompileError::InvalidInstruction {
  725. //
  726. instruction: opcode.to_string(), //
  727. span: span.clone(), //
  728. custom_label: Some(
  729. EXPECTS_REG_COM_IMM_COM_IMM_OR_IDEN.to_string(),
  730. ),
  731. });
  732. }
  733. }
  734. next_token_num = 6;
  735. }
  736. }
  737. }
  738. Opcode::Neg32 | Opcode::Neg64 => {
  739. if tokens.len() < 2 {
  740. return Err(CompileError::InvalidInstruction {
  741. //
  742. instruction: opcode.to_string(), //
  743. span: span.clone(), //
  744. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  745. });
  746. }
  747. match &tokens[1] {
  748. Token::Register(_, _) => {
  749. operands.push(tokens[1].clone());
  750. }
  751. _ => {
  752. return Err(CompileError::InvalidInstruction {
  753. //
  754. instruction: opcode.to_string(), //
  755. span: span.clone(), //
  756. custom_label: Some(EXPECTS_REG.to_string()),
  757. });
  758. }
  759. }
  760. next_token_num = 2;
  761. }
  762. Opcode::Ja => {
  763. if tokens.len() < 2 {
  764. return Err(CompileError::InvalidInstruction {
  765. //
  766. instruction: opcode.to_string(), //
  767. span: span.clone(), //
  768. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  769. });
  770. }
  771. let (value, advance_token_num) =
  772. inline_and_fold_constant(tokens, const_map, 1);
  773. if let Some(value) = value {
  774. operands.push(Token::ImmediateValue(value, span.clone()));
  775. next_token_num = advance_token_num;
  776. } else {
  777. match &tokens[1] {
  778. Token::Identifier(_, _) => {
  779. operands.push(tokens[1].clone());
  780. }
  781. _ => {
  782. return Err(CompileError::InvalidInstruction {
  783. //
  784. instruction: opcode.to_string(), //
  785. span: span.clone(), //
  786. custom_label: Some(EXPECTS_IDEN.to_string()),
  787. });
  788. }
  789. }
  790. next_token_num = 2;
  791. }
  792. }
  793. Opcode::Call => {
  794. if tokens.len() < 2 {
  795. return Err(CompileError::InvalidInstruction {
  796. //
  797. instruction: opcode.to_string(), //
  798. span: span.clone(), //
  799. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  800. });
  801. }
  802. match &tokens[1] {
  803. Token::Identifier(_, _) => {
  804. operands.push(tokens[1].clone());
  805. }
  806. _ => {
  807. return Err(CompileError::InvalidInstruction {
  808. //
  809. instruction: opcode.to_string(), //
  810. span: span.clone(), //
  811. custom_label: Some(EXPECTS_IDEN.to_string()),
  812. });
  813. }
  814. }
  815. next_token_num = 2;
  816. }
  817. Opcode::Callx => {
  818. if tokens.len() < 2 {
  819. return Err(CompileError::InvalidInstruction {
  820. //
  821. instruction: opcode.to_string(), //
  822. span: span.clone(), //
  823. custom_label: Some(EXPECTS_MORE_OPERAND.to_string()),
  824. });
  825. }
  826. match &tokens[1] {
  827. Token::Register(_, _) => {
  828. operands.push(tokens[1].clone());
  829. }
  830. _ => {
  831. return Err(CompileError::InvalidInstruction {
  832. //
  833. instruction: opcode.to_string(), //
  834. span: span.clone(), //
  835. custom_label: Some(EXPECTS_IDEN.to_string()),
  836. });
  837. }
  838. }
  839. next_token_num = 2;
  840. }
  841. Opcode::Exit => {
  842. next_token_num = 1;
  843. }
  844. _ => {
  845. bug!("invalid opcode: {}", opcode.to_str());
  846. }
  847. }
  848. Ok((
  849. Instruction {
  850. opcode,
  851. operands,
  852. span: span.clone(),
  853. },
  854. &tokens[next_token_num..],
  855. ))
  856. }
  857. _ => {
  858. bug!("invalid instruction");
  859. }
  860. }
  861. }
  862. }
  863. fn parse_vector_literal(
  864. tokens: &[Token],
  865. stack: &mut Vec<ImmediateValue>,
  866. start_idx: usize,
  867. ) -> usize {
  868. let mut idx = start_idx;
  869. while idx < tokens.len() - 1 {
  870. match (&tokens[idx], &tokens[idx + 1]) {
  871. (Token::Comma(_), Token::ImmediateValue(val, _)) => {
  872. stack.push(val.clone());
  873. idx += 2;
  874. }
  875. _ => {
  876. break;
  877. }
  878. }
  879. }
  880. idx
  881. }
  882. fn fold_top(stack: &mut Vec<Token>) {
  883. if stack.len() < 3 {
  884. return;
  885. }
  886. if let (
  887. Token::ImmediateValue(val1, _),
  888. Token::BinaryOp(op, _),
  889. Token::ImmediateValue(val2, span),
  890. ) = (
  891. stack[stack.len() - 3].clone(),
  892. stack[stack.len() - 2].clone(),
  893. stack[stack.len() - 1].clone(),
  894. ) {
  895. let result = match op {
  896. Op::Add => val1.clone() + val2.clone(),
  897. Op::Sub => val1.clone() - val2.clone(),
  898. Op::Mul => val1.clone() * val2.clone(),
  899. Op::Div => val1.clone() / val2.clone(),
  900. };
  901. stack.pop();
  902. stack.pop();
  903. stack.pop();
  904. stack.push(Token::ImmediateValue(result, span));
  905. }
  906. }
  907. fn inline_and_fold_constant(
  908. tokens: &[Token],
  909. const_map: &std::collections::HashMap<String, ImmediateValue>,
  910. start_idx: usize,
  911. ) -> (Option<ImmediateValue>, usize) {
  912. inline_and_fold_constant_with_map(tokens, Some(const_map), start_idx)
  913. }
  914. fn inline_and_fold_constant_with_map(
  915. tokens: &[Token],
  916. const_map: Option<&std::collections::HashMap<String, ImmediateValue>>,
  917. start_idx: usize,
  918. ) -> (Option<ImmediateValue>, usize) {
  919. let mut stack: Vec<Token> = Vec::new();
  920. let mut expect_number = true;
  921. let mut idx = start_idx;
  922. while idx < tokens.len() {
  923. match &tokens[idx] {
  924. Token::ImmediateValue(val, span) if expect_number => {
  925. stack.push(Token::ImmediateValue(val.clone(), span.clone()));
  926. expect_number = false;
  927. // Immediately fold * / if top
  928. if stack.len() > 2
  929. && let Token::BinaryOp(op, _) = &stack[stack.len() - 2]
  930. && matches!(op, Op::Mul | Op::Div)
  931. {
  932. fold_top(&mut stack);
  933. }
  934. }
  935. Token::Identifier(name, span) if expect_number => {
  936. if let Some(const_map) = const_map {
  937. if let Some(val) = const_map.get(name) {
  938. stack.push(Token::ImmediateValue(val.clone(), span.clone()));
  939. expect_number = false;
  940. if stack.len() > 2
  941. && let Token::BinaryOp(op, _) = &stack[stack.len() - 2]
  942. && matches!(op, Op::Mul | Op::Div)
  943. {
  944. fold_top(&mut stack);
  945. }
  946. } else {
  947. return (None, idx);
  948. }
  949. } else {
  950. // error out would be better here
  951. return (None, idx);
  952. }
  953. }
  954. Token::BinaryOp(op, span) => {
  955. match op {
  956. Op::Sub if expect_number => {
  957. // unary minus → 0 - expr
  958. stack.push(Token::ImmediateValue(ImmediateValue::Int(0), span.clone()));
  959. stack.push(Token::BinaryOp(Op::Sub, span.clone()));
  960. }
  961. _ => {
  962. stack.push(Token::BinaryOp(op.clone(), span.clone()));
  963. }
  964. }
  965. expect_number = true;
  966. }
  967. Token::LeftParen(span) => {
  968. // Parse inside parentheses
  969. let (inner_val, new_idx) =
  970. inline_and_fold_constant_with_map(tokens, const_map, idx + 1);
  971. idx = new_idx;
  972. if let Some(v) = inner_val {
  973. stack.push(Token::ImmediateValue(v, span.clone()));
  974. expect_number = false;
  975. if stack.len() > 2
  976. && let Token::BinaryOp(op, _) = &stack[stack.len() - 2]
  977. && matches!(op, Op::Mul | Op::Div)
  978. {
  979. fold_top(&mut stack);
  980. }
  981. } else {
  982. return (None, idx);
  983. }
  984. continue; // skip normal idx++
  985. }
  986. Token::RightParen(_) => {
  987. // fold remaining + and -
  988. while stack.len() > 2 {
  989. fold_top(&mut stack);
  990. }
  991. if let Token::ImmediateValue(v, _) = &stack[0] {
  992. return (Some(v.clone()), idx + 1);
  993. } else {
  994. return (None, idx + 1);
  995. }
  996. }
  997. _ => {
  998. // Unexpected token, stop
  999. break;
  1000. }
  1001. }
  1002. idx += 1;
  1003. }
  1004. // Final fold at the end of expression
  1005. while stack.len() > 2 {
  1006. fold_top(&mut stack);
  1007. }
  1008. if let Some(Token::ImmediateValue(v, _)) = stack.pop() {
  1009. (Some(v), idx)
  1010. } else {
  1011. (None, idx)
  1012. }
  1013. }
  1014. pub fn parse_tokens(mut tokens: &[Token]) -> Result<ParseResult, Vec<CompileError>> {
  1015. let mut ast = AST::new();
  1016. let mut rodata_phase = false;
  1017. let mut accum_offset = 0;
  1018. let mut rodata_accum_offset = 0;
  1019. let mut const_map = HashMap::<String, ImmediateValue>::new();
  1020. let mut label_spans = HashMap::<String, std::ops::Range<usize>>::new();
  1021. let mut errors = Vec::new();
  1022. while !tokens.is_empty() {
  1023. match &tokens[0] {
  1024. Token::Directive(name, span) => match name.as_str() {
  1025. "global" | "globl" => match GlobalDecl::parse(tokens) {
  1026. Ok((node, rest)) => {
  1027. ast.entry_label = Some(node.get_entry_label());
  1028. ast.nodes.push(ASTNode::GlobalDecl { global_decl: node });
  1029. tokens = rest;
  1030. }
  1031. Err(e) => {
  1032. errors.push(e);
  1033. tokens = &tokens[1..];
  1034. }
  1035. },
  1036. "extern" => match ExternDecl::parse(tokens) {
  1037. Ok((node, rest)) => {
  1038. ast.nodes.push(ASTNode::ExternDecl { extern_decl: node });
  1039. tokens = rest;
  1040. }
  1041. Err(e) => {
  1042. errors.push(e);
  1043. tokens = &tokens[1..];
  1044. }
  1045. },
  1046. "text" => {
  1047. rodata_phase = false;
  1048. tokens = &tokens[1..];
  1049. }
  1050. "rodata" => {
  1051. ast.nodes.push(ASTNode::RodataDecl {
  1052. rodata_decl: RodataDecl { span: span.clone() },
  1053. });
  1054. rodata_phase = true;
  1055. tokens = &tokens[1..];
  1056. }
  1057. "equ" => match EquDecl::parse_with_constmap(tokens, &const_map) {
  1058. Ok((node, rest)) => {
  1059. const_map.insert(node.get_name(), node.get_val());
  1060. ast.nodes.push(ASTNode::EquDecl { equ_decl: node });
  1061. tokens = rest;
  1062. }
  1063. Err(e) => {
  1064. errors.push(e);
  1065. tokens = &tokens[1..];
  1066. }
  1067. },
  1068. "section" => {
  1069. ast.nodes.push(ASTNode::Directive {
  1070. directive: Directive {
  1071. name: name.clone(),
  1072. args: Vec::new(),
  1073. span: span.clone(),
  1074. },
  1075. });
  1076. tokens = &tokens[1..];
  1077. }
  1078. _ => {
  1079. errors.push(CompileError::InvalidDirective {
  1080. directive: name.clone(),
  1081. span: span.clone(),
  1082. custom_label: None,
  1083. });
  1084. tokens = &tokens[1..];
  1085. }
  1086. },
  1087. Token::Label(name, span) => {
  1088. if rodata_phase {
  1089. match ROData::parse(tokens) {
  1090. Ok((rodata, rest)) => {
  1091. if label_spans.contains_key(name) {
  1092. let original_span =
  1093. label_spans.get(name).cloned().unwrap_or(span.clone());
  1094. errors.push(CompileError::DuplicateLabel {
  1095. label: name.clone(),
  1096. span: span.clone(),
  1097. original_span,
  1098. custom_label: Some(LABEL_REDEFINED.to_string()),
  1099. });
  1100. } else {
  1101. label_spans.insert(name.clone(), span.clone());
  1102. if let Err(e) = rodata.verify() {
  1103. errors.push(e);
  1104. }
  1105. }
  1106. let rodata_size = rodata.get_size();
  1107. ast.rodata_nodes.push(ASTNode::ROData {
  1108. rodata,
  1109. offset: rodata_accum_offset,
  1110. });
  1111. rodata_accum_offset += rodata_size;
  1112. tokens = rest;
  1113. }
  1114. Err(e) => {
  1115. errors.push(e);
  1116. tokens = &tokens[1..];
  1117. }
  1118. }
  1119. } else {
  1120. if label_spans.contains_key(name) {
  1121. let original_span = label_spans.get(name).cloned().unwrap_or(span.clone());
  1122. errors.push(CompileError::DuplicateLabel {
  1123. label: name.clone(),
  1124. span: span.clone(),
  1125. original_span,
  1126. custom_label: Some(LABEL_REDEFINED.to_string()),
  1127. });
  1128. } else {
  1129. label_spans.insert(name.clone(), span.clone());
  1130. }
  1131. ast.nodes.push(ASTNode::Label {
  1132. label: Label {
  1133. name: name.clone(),
  1134. span: span.clone(),
  1135. },
  1136. offset: accum_offset,
  1137. });
  1138. tokens = &tokens[1..];
  1139. }
  1140. }
  1141. Token::Opcode(_, _) => match Instruction::parse_with_constmap(tokens, &const_map) {
  1142. Ok((inst, rest)) => {
  1143. let offset = accum_offset;
  1144. accum_offset += inst.get_size();
  1145. ast.nodes.push(ASTNode::Instruction {
  1146. instruction: inst,
  1147. offset,
  1148. });
  1149. tokens = rest;
  1150. }
  1151. Err(e) => {
  1152. errors.push(e);
  1153. tokens = &tokens[1..];
  1154. }
  1155. },
  1156. _ => {
  1157. tokens = &tokens[1..];
  1158. }
  1159. }
  1160. }
  1161. if !errors.is_empty() {
  1162. return Err(errors);
  1163. }
  1164. ast.set_text_size(accum_offset);
  1165. ast.set_rodata_size(rodata_accum_offset);
  1166. let parse_result = ast.build_program();
  1167. if let Ok(parse_result) = parse_result {
  1168. Ok(parse_result)
  1169. } else {
  1170. Err(parse_result.err().unwrap())
  1171. }
  1172. }