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

Fix inconsistency with add operator, Added switch/case, Added default block values, Filter block with format function #93

Closed
wants to merge 0 commits into from

Conversation

maxime1907
Copy link

Add:
"2" + 1 - output: 3
1 + "2" - output: 3
"2" + "2" - output: 4
"2" + "2z" - output: 22z

Switch/Case with empty case as default :
{{ switch power }}
{{ case 10 }}
Value is 10
{{ end }}
{{ case }}
This is default case
{{ end }}
{{ end }}

Default block:

  • Example 1:
    {{ Size = 10 }}
    {{ default }}
    {{ Size = 20 }}
    {{ end }}
    Size is {{ Size }} cm
    output : Size is 10 cm

  • Example 2:
    {{ default }}
    {{ Size = 20 }}
    {{ end }}
    Size is {{ Size }} cm
    output : Size is 20 cm

Filter block with format function:
{{ filter format("<-- %v -->") }}
This is
formatted text
{{ end }}
output:
<-- This is -->
<-- formatted text -->

@annismckenzie
Copy link
Member

What is happening all of a sudden? Ho-ly! This is major. You seem to have a good grasp on the whole parser and lexer business (*makes-a-mental-note*).

This is a lot to unpack and we'll need multiple rounds of reviews – hope you're up for that. I might also opt for splitting this up into multiple PRs.

I'll do an initial review this evening.

Also, this needs some emojis: 🎉🎉🎉

template.go Outdated
@@ -371,6 +372,9 @@ func (scope VarMap) SetWriter(name string, v SafeWriter) VarMap {

// Execute executes the template in the w Writer
func (t *Template) Execute(w io.Writer, variables VarMap, data interface{}) error {
if w == nil {
Copy link
Member

Choose a reason for hiding this comment

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

This default we should skip, we need to fail when the user pass an nil writer. We can even panic with a descriptive error message.

eval.go Outdated
@@ -549,6 +760,38 @@ var (
valueBoolFALSE = reflect.ValueOf(false)
)

func ParseIndexExpr(baseExpression reflect.Value, indexExpression reflect.Value, indexType reflect.Type) (reflect.Value, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Can you refactor this function in to private ? I think is better to export only the names meant to be used by the user.

Copy link
Member

Choose a reason for hiding this comment

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

I'd also add it to the Runtime struct like the other expression parsing methods.

@jhsx
Copy link
Member

jhsx commented Jul 4, 2018

Thanks for your contributions 👍 .

eval.go Outdated
@@ -649,6 +869,40 @@ func (st *Runtime) evalPrimaryExpressionGroup(node Expression) reflect.Value {
return st.evalBaseExpressionGroup(node)
}

func ParseByType(baseExpression reflect.Value, indexExpression reflect.Value, indexType reflect.Type) (bool, error) {
Copy link
Member

Choose a reason for hiding this comment

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

This one also.

@annismckenzie
Copy link
Member

I'm gonna pull #32 into the discussion:

I propose a breaking change in the template language, adding a operator for string concatenation and let numeric operators to work only with numbers.
Like php $val.$val2.

I agreed with it then and I agree with it now. Addition should only apply to numeric parts and we should add the dot operator (or something else) to concatenate strings where numeric components are cast to strings. Whatever we decide we should move those code changes to a separate PR that references #32 and if we decide that we instead want it this way then that's fine too. Can you move the commits over to a separate branch, please?

@@ -130,4 +130,4 @@ func main() {

log.Println("Serving on " + port)
http.ListenAndServe(port, nil)
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Please don't drop empty lines at the end of files, it trips up Git's diff algorithm from time to time and makes staging single-line hunks unreliable. If you don't have it yet, add https://editorconfig.org to your editor and configure it with

[*]
end_of_line = lf
insert_final_newline = true

for the Jet repository (we can add that config file to the .gitignore if need be).

lex.go Outdated
"content": itemContent,
"msg": itemMSG,
"trans": itemTrans,
"extends": itemExtends,
Copy link
Member

Choose a reason for hiding this comment

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

It doesn't look like you're using go fmt? Always use go fmt in Go projects.

node.go Outdated
@@ -79,6 +79,10 @@ const (
nodeEnd //An end action. Not added to tree.
NodeField //A field or method name.
NodeIdentifier //An identifier; always a function name.
NodeDefault //A default action
Copy link
Member

Choose a reason for hiding this comment

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

Same here, go fmt takes care of this for you.

.gitignore Outdated
.idea
sftp-config.json
Copy link
Member

Choose a reason for hiding this comment

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

Undo this change, it doesn't belong.

@@ -1,2 +0,0 @@
# fastprinter
Copy link
Member

Choose a reason for hiding this comment

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

Please undo removing these files. They were added to prevent people from having to add yet another library dependency and is actually small enough to warrant being in this repository.

eval.go Outdated
switch node.Type() {
case NodeAction:
node := node.(*ActionNode)

Copy link
Member

Choose a reason for hiding this comment

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

drop this empty line

eval.go Outdated
}
}
}
case NodeDefault:
node := node.(*DefaultNode)

Copy link
Member

Choose a reason for hiding this comment

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

Can you drop the surrounding empty lines here and also in the following case statements?

@annismckenzie
Copy link
Member

A couple more things and some comments to sum up how I'd like to continue this:

  1. What's the use case {{ filter format("something") }} being added to the language? I can't think of a situation right now where I'd use it. 🤔
  2. The switch/case is valuable, as is the default block so these can go in together. 👍
  3. The add operator inconsistency check code should be moved to a separate branch. That will likely also result in this being included in the v2.2.0 release instead of being moved to v3.0.
  4. Various nits with code formatting.
  5. Test coverage of these changes is 0 which we'll need to change before merging.

In see you committed this straight to your fork's master branch which is a weird thing to do. 😬 So, I can help with all of those chores and nits if you want. You enabled maintainers being able to add commits so just say the word and I'll jump in. It's really great to get contributions and you'll be added to the contributors section in the README which I still haven't done (#60) but will soon. 🎉

@mvrhov
Copy link

mvrhov commented Jul 5, 2018

IMO the default shouldn't be a block, but a pipeline "filter".

@maxime1907
Copy link
Author

maxime1907 commented Jul 5, 2018

@mvrhov I agree that it would be nice to add the default block to filter functions but the meaning of using a filter is to actually impact what is contained within this node
For instance, we could later add a upper/lower function that will impact inner text, and in a default block you can't do anything other than writing variable assignations
@annismckenzie Thank you for your relevant remarks and to answer your questions:

  1. I need to use this template engine for telephony configuration purposes and a bunch of them are requiring to have a special formatting on all lines
  2. Yes i needed it
  3. Take a look at the issue, i'll answer it
  4. Coding style ^^ but np
  5. I manually test my functions and that's not my cup of tea 😄
    You can do whatever you want, i am only interested in adding functionalities for now so change what seems wrong to you :)
    Also, take a look at perl template engine http://template-toolkit.org/docs/manual/ , it is very helpful and you will understand why i need a filter block ^^

@mvrhov
Copy link

mvrhov commented Jul 5, 2018

No really I don't see the value of a default block.
Why doesn't this work work you? Size is {{ Size|default(20) }} cm, because Size might have not be defined? The default pipe should handle that.
e.g https://twig.symfony.com/doc/2.x/filters/default.html

@maxime1907
Copy link
Author

maxime1907 commented Jul 5, 2018

I don't really have a preference, i just looked at http://www.template-toolkit.org/docs/manual/Directives.html#section_DEFAULT and thought it may be a good idea but if you have a preference then let's do this ^^

@mvrhov
Copy link

mvrhov commented Jul 10, 2018

👍 for default as a filter implementation. It's more readable and less typing

@maxime1907
Copy link
Author

Have i done what you wanted me to fix ? If so, can you consider accepting my pull request ? 😄

@@ -178,7 +187,7 @@ func PrintValue(w io.Writer, v reflect.Value) (int, error) {
return PrintUint(w, v.Uint())
}

if k == reflect.Float64 || k == reflect.Float32 {
if k == reflect.Float64 || k == reflect.Float64 {
Copy link
Member

Choose a reason for hiding this comment

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

Did you copy this in? It's the same comparison on both sides now which is very weird.

Copy link
Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

I'll open a separate MR about this later. For now, I reverted to the previous version of the vendored code and opened #94.

@annismckenzie
Copy link
Member

Thanks for all the changes! I'll be going through this tomorrow. I'm also going to have to do a rebase against the current master.

@tooolbox
Copy link
Contributor

tooolbox commented Jul 16, 2018

@annismckenzie Another use case for "filter" would be to pipe a block through quotedprintable when you're rendering emails to send via smtp.

EDIT: Although...I realize with the way it's implemented, it wouldn't work for that use case 😶

Exciting! Well done @maxime1907

@annismckenzie
Copy link
Member

Oh GitHub! That »collaborators can just push to that branch« is really really weird and I made a mistake that zeroed out your branch. And because I did that it closed the MR and also removed the permission for me to fix it. I did rework your commits and they still contain your author name and email. Can I trouble you to push your commits again and reopen the MR? So sorry about this. 😖

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants