Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First stab at format args and a working println macro #141

Merged
merged 2 commits into from
Oct 8, 2020

Conversation

udoprog
Copy link
Collaborator

@udoprog udoprog commented Oct 8, 2020

This PR introduces the necessary plumbing to implement the Rune equivalent of Rust's println! macro.

This will eventually be pulled and made into re-usable code so that it can be re-used with other macros that wants to use format specifications (assert!, assert_eq!, etc...).

The macro is implemented like the following:

  • Template strings are expanded to #[builtin] template!("Hello ", a) (instead of template { "Hello ", a }, which required a special keyword.
  • Format specifications are expanded to #[builtin] format_spec!(value, type = debug) (if debug).

The #[builtin] attribute changes naming resolution for macros to look for compiler built-in macros. These are macros which expand internally to BuiltInMacro variants, and the macro AST is assigned the appropriate ID so that it can look up the implementation during assembly. It also acts as a sentinel which nukes the compilation in case we forget to expand it. I.e. all attributes need to be consumed one way or another, and if we fail to expand the internal macros, they won't be and compilation will fail.

This allows us to use and implement internal macros which can do some special things. In this case, an expansion of format_spec! results in using the newly introduced FormatSpec instruction to build the newly introduced FormatSpec object, which has a few tricks up its sleeve when combined with concat-strings.

Ultimately this means that the following macro invocation:

println!("Hello {:?}", "World");

Is expanded to:

std::io::println(#[builtin] template!("Hello ", #[builtin] format_spec!("World", type = debug)))

Or... the following instructions:

  0000 = string 0
  0001 = string 1
  0002 = format-spec debug
  0003 = string-concat 2, 6
  0004 = call 0x4e01f6aa154b0c5, 1 // fn std::io::println

Currently only the following format specifications are supported:

  • Positional arguments (i.e. {}).
  • Numbered arguments (i.e. {2}).
  • Named arguments (i.e. {foo}).
  • Specify debug type (i.e. {foo:?}).

Also note that only a limited subset of types are supported through string-concat right now. And the implementation needs to be cleaned up A LOT.

@udoprog udoprog added the enhancement New feature or request label Oct 8, 2020
@udoprog udoprog merged commit 5974aab into master Oct 8, 2020
@udoprog udoprog deleted the first-stab-format-args branch October 8, 2020 19:35
@udoprog udoprog added the changelog Issue has been added to the changelog label Oct 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog Issue has been added to the changelog enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant