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

Enhance Color #71

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 66 additions & 6 deletions pax-compiler/src/parsing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ fn recurse_pratt_parse_to_string<'a>(
Rule::expression_grouped => {
/* expression_grouped = { "(" ~ expression_body ~ ")" ~ literal_number_unit? } */
let mut inner = primary.into_inner();

let exp_bod = recurse_pratt_parse_to_string(inner.next().unwrap().into_inner(), pratt_parser, Rc::clone(&symbolic_ids));
if let Some(literal_number_unit) = inner.next() {
let unit = literal_number_unit.as_str();
Expand All @@ -110,10 +109,18 @@ fn recurse_pratt_parse_to_string<'a>(
xo_function_args_list = {expression_body ~ ("," ~ expression_body)*} */

//prepend identifiers; recurse-pratt-parse `xo_function_args`' `expression_body`s
let mut pairs = primary.into_inner();

let mut pairs = primary.clone().into_inner();
let mut output = "".to_string();
let mut next_pair = pairs.next().unwrap();
match next_pair.as_rule() {
Rule::literal_color => {
return recurse_pratt_parse_to_string(primary.into_inner(), pratt_parser, Rc::clone(&symbolic_ids));
}
Rule::literal_hex_color => {
return recurse_pratt_parse_to_string(pairs, pratt_parser, Rc::clone(&symbolic_ids));
}
_=>()
}
while let Rule::identifier = next_pair.as_rule() {
output = output + next_pair.as_str();
next_pair = pairs.next().unwrap();
Expand Down Expand Up @@ -172,8 +179,7 @@ fn recurse_pratt_parse_to_string<'a>(
format!("{}", op0_out + &op1_out + &op2_out)
},
Rule::xo_literal => {
let literal_kind = primary.into_inner().next().unwrap();

let literal_kind = primary.clone().into_inner().next().unwrap();
match literal_kind.as_rule() {
Rule::literal_number_with_unit => {
let mut inner = literal_kind.into_inner();
Expand Down Expand Up @@ -201,12 +207,34 @@ fn recurse_pratt_parse_to_string<'a>(
Rule::string => {
format!("StringBox::from({})",literal_kind.as_str().to_string())
},
Rule::literal_color => {
return recurse_pratt_parse_to_string(literal_kind.into_inner(), pratt_parser, Rc::clone(&symbolic_ids));
},
Rule::literal_hex_color => {
return recurse_pratt_parse_to_string(primary.into_inner(), pratt_parser, Rc::clone(&symbolic_ids));
}
_ => {
/* {literal_enum_value | literal_tuple_access | literal_tuple | string } */
literal_kind.as_str().to_string()
}
}
},
Rule::literal_color => {
let color_format = primary.as_str();
return parse_rgb_color(primary,color_format);
},
Rule::literal_hex_color => {
let hex = primary.as_str();
let hex = hex.trim().trim_start_matches('#');
let r = u8::from_str_radix(&hex[0..2], 16).expect("Invalid hex value for red") as f64;
let g = u8::from_str_radix(&hex[2..4], 16).expect("Invalid hex value for green") as f64;
let b = u8::from_str_radix(&hex[4..6], 16).expect("Invalid hex value for blue") as f64;

let r = format!("Size::Percent({}.into())",(r/255.0)*100.0);
let g = format!("Size::Percent({}.into())",(g/255.0)*100.0);
let b = format!("Size::Percent({}.into())",(b/255.0)*100.0);
format!("Color::rgb({r},{g},{b}).into()")
}
Rule::xo_object => {
let mut output : String = "".to_string();

Expand Down Expand Up @@ -269,7 +297,8 @@ fn recurse_pratt_parse_to_string<'a>(
Rule::expression_body => {
recurse_pratt_parse_to_string(primary.into_inner(), pratt_parser, Rc::clone(&symbolic_ids))
},
_ => unreachable!("{}",primary.as_str()),

_ => unreachable!("{:#?}",primary.as_str()),
})
.map_prefix(|op, rhs| match op.as_rule() {
Rule::xo_neg => format!("(-{})", rhs),
Expand Down Expand Up @@ -302,6 +331,37 @@ fn recurse_pratt_parse_to_string<'a>(
.parse(expression)
}

fn parse_rgb_color(color: Pair<'_, Rule>, color_format: &str) -> String {
let mut inner = color.into_inner();

let r = inner.next().unwrap().as_str().replace("%", "");
let g = inner.next().unwrap().as_str().replace("%", "");
let b = inner.next().unwrap().as_str().replace("%", "");
let a = inner
.next()
.map(|x| x.as_str().replace("%", ""))
.unwrap_or("1".to_string());

let r = format!("Size::Percent({}.into())", r);
let g = format!("Size::Percent({}.into())", g);
let b = format!("Size::Percent({}.into())", b);
let a = format!("Size::Percent({}.into())", a);

let comma_count = color_format.chars().filter(|&c| c == ',').count();

if color_format.starts_with("rgb(") && comma_count == 2 {
format!("Color::rgb({r},{g},{b}).into()")
} else if color_format.starts_with("rgba(") && comma_count == 3 {
format!("Color::rgba({r},{g},{b},{a}).into()")
} else if color_format.starts_with("hlc(") && comma_count == 2 {
format!("Color::hlc({r},{g},{b}).into()")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this code path is being hit. When I try fill={hlc((ticks + i * 360.0 * 3)%, 50%, 50%)} in the Fireworks example, I get an error:

168 | ...   hlc((Size::Percent((ticks +((i *(Numeric::from(360.0 )).into())*(Numer...
    |       ^^^ not found in this scope

My best guess from a quick look is that we might be short-circuiting this on line 211 of this file: https://github.com/pax-lang/pax/pull/71/files#diff-3bfd18387cf178bec2da888bfa3aadadd3de4522ed242e2b303877b0a3dcb855R211 , but the issue might be something else entirely.

} else if color_format.starts_with("hlca(") && comma_count == 3 {
format!("Color::hlca({r},{g},{b},{a}).into()")
} else {
panic!("Invalid color format: {}", color_format)
}
}

fn parse_template_from_component_definition_string(ctx: &mut TemplateNodeParseContext, pax: &str) {
let pax_component_definition = PaxParser::parse(Rule::pax_component_definition, pax)
.expect(&format!("unsuccessful parse from {}", &pax)) // unwrap the parse result
Expand Down
9 changes: 6 additions & 3 deletions pax-compiler/src/pax.pest
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,17 @@ handlers_value = { literal_function | function_list }
literal_function = { "self."? ~ identifier ~ ","? }
function_list = {"[" ~ literal_function* ~ "]"}

literal_value = { literal_number_with_unit | literal_number | literal_tuple | literal_enum_value | literal_boolean | string }
literal_value = { literal_number_with_unit | literal_number | literal_color | literal_hex_color | literal_enum_value | literal_boolean | string | literal_tuple}
literal_number_with_unit = { literal_number ~ literal_number_unit }
literal_number = {"-"? ~ (literal_number_float | literal_number_integer)}
literal_number_integer = {(!(".") ~ ASCII_DIGIT)+ }
literal_number_float = {ASCII_DIGIT* ~ "." ~ ASCII_DIGIT+}
literal_number_unit = {("%" | "px" | "deg" | "rad")}
literal_tuple = {("(") ~ literal_value ~ ("," ~ literal_value)* ~ (")")}
literal_boolean = {("true" | "false")}
literal_color = {(("rgb(") | ("rgba(")| ("hlc(")| ("hlca(")) ~ literal_number_with_unit ~ ("," ~ literal_number_with_unit)* ~ ("," ~ literal_number_with_unit)* ~ (")")}
literal_mixed_hex = { '0'..'9' | (('a'..'f') | ('A'..'F'))}
literal_hex_color = {"#" ~ literal_mixed_hex{6}}


//Enums like Orientation::Vertical or Color::Rgba(100%, 100%, 0, 0)
Expand Down Expand Up @@ -215,7 +218,7 @@ xo_range = { (xo_literal | xo_symbol) ~ (xo_range_exclusive) ~ (xo_literal | xo_
xo_range_exclusive = @{".."}
// xo_range_inclusive = @{"..="}

xo_literal = {literal_enum_value | literal_tuple_access | literal_number_with_unit | literal_number | string | literal_tuple }
xo_literal = {literal_enum_value | literal_tuple_access | literal_number_with_unit | literal_number | string | literal_tuple | literal_color | literal_hex_color }

//objects may recurse into arbitrary expressions for any value -- consider the `key_2` in:
// `some_prop={ TypedReturn {key_0: 0, key_1: "one", key_2: 1.0 + 1.0} }`
Expand All @@ -226,7 +229,7 @@ xo_symbol = { "$"? ~ identifier ~ (("." ~ identifier) | ("[" ~ expression_body ~
xo_tuple = { "(" ~ expression_body ~ ("," ~ expression_body)* ~ ")"}
xo_list = { "[" ~ (expression_body ~ ("," ~ expression_body)*)? ~ "]" }

xo_function_call = {identifier ~ (("::") ~ identifier)* ~ ("("~xo_function_args_list~")")}
xo_function_call = { literal_color | identifier ~ (("::") ~ identifier)* ~ ("("~xo_function_args_list~")")}
xo_function_args_list = {(expression_body ~ ("," ~ expression_body)*)?}

////// ////// //////
Expand Down
2 changes: 1 addition & 1 deletion pax-compiler/templates/cartridge-lib.tera
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub fn instantiate_expression_table<R: 'static + RenderContext>() -> HashMap<usi
{% endif %}

TypesCoproduct::{{ expression_spec.pascalized_return_type }}(
{{ expression_spec.output_statement }}
{{ expression_spec.output_statement }}.into()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is problematic. I set up repro here:
https://github.com/pax-lang/pax/compare/6df4802c6b32^...78fb7765dcb2#diff-22275c553b4a7bfe13d35b04f59015dba9373818c30049484349acdb2a4627f4L3

I started with your branch, rebased off of origin/master so we have Warfa's latest work on /examples, then modified the fireworks example to be able to reproduce the error I'm seeing related to this .into.

You should be able to reproduce by pulling the branch oa/pax_qualia (from this repo) and running cargo run --examples fireworks. The error:

error[E0277]: the trait bound `isize: From<i32>` is not satisfied
   --> /Users/zack/code/pax/examples/src/fireworks/.pax/pkg/pax-cartridge/src/lib.rs:110:19
    |
110 |             0..60.into()
    |                   ^^^^ the trait `From<i32>` is not implemented for `isize`

This is on the range expression for i in 0..60 — the addition of the .into breaks that range literal. If we need to add an additional .into for Color, can it be higher in the codegen than this terminal statement? Because of the constraints around the graph of types we can into, each new into comes with a cost, so is it possible to drop this one entirely?

)
}));
{% endfor %}
Expand Down
Loading