winglang / wing

A programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡
https://winglang.io
Other
4.77k stars 189 forks source link

Many compiler parse errors #6549

Closed eladb closed 1 month ago

eladb commented 1 month ago

I tried this:

bring "./namer.w" as n;
bring cloud;
bring openai;

let oaik = new cloud.Secret(name: "OPENAI_KEY") as "openai_key";
let model = new openai.OpenAI(apiKeySecret: oaik) as "gpt_4o";

let namer = new n.Namer(model: model);

let examples = [
  "this is the content i want to use to create a file name",
  "this is another content i want to use to create a file name",
  "this is a third content i want to use to create a file name",
  "a poem about the ocean",
  "a poem about the sky",
  "some big string: 1234567890!@#$%^&*()_+",
];

new cloud.Function(inflight () => {
  for e in examples {
    let name = namer.makeFileName(e);
    log(name);
  }
});

bring expect;
test "create a file name" {
  let response = namer.makeFileName("this is the content i want to use to create a file name");

  expect.equal(response, {
    "mock":{
      "max_tokens":2048,
      "model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
}

This happened:

Failed to compile.

error: Unexpected 'import_statement'
  --> namer.test.w:1:1
  |
1 | bring "./namer.w" as n;
  | ^^^^^^^^^^^^^^^^^^^^^^^

error: Unexpected 'import_statement'
  --> namer.test.w:2:1
  |
2 | bring cloud;
  | ^^^^^^^^^^^^

error: Unexpected 'import_statement'
  --> namer.test.w:3:1
  |
3 | bring openai;
  | ^^^^^^^^^^^^^

error: Unexpected 'variable_definition_statement'
  --> namer.test.w:5:1
  |
5 | let oaik = new cloud.Secret(name: "OPENAI_KEY") as "openai_key";
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: Unexpected 'variable_definition_statement'
  --> namer.test.w:6:1
  |
6 | let model = new openai.OpenAI(apiKeySecret: oaik) as "gpt_4o";
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: Unexpected 'variable_definition_statement'
  --> namer.test.w:8:1
  |
8 | let namer = new n.Namer(model: model);
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: Unexpected 'variable_definition_statement'
   --> namer.test.w:10:1
   |  
10 | / let examples = [
11 | |   "this is the content i want to use to create a file name",
12 | |   "this is another content i want to use to create a file name",
13 | |   "this is a third content i want to use to create a file name",
   . |
16 | |   "some big string: 1234567890!@#$%^&*()_+",
17 | | ];
   | \--^

error: Unexpected 'expression_statement'
   --> namer.test.w:19:1
   |  
19 | / new cloud.Function(inflight () => {
20 | |   for e in examples {
21 | |     let name = namer.makeFileName(e);
22 | |     log(name);
23 | |   }
24 | | });
   | \---^

error: Unexpected 'import_statement'
   --> namer.test.w:27:1
   |
27 | bring expect;
   | ^^^^^^^^^^^^^

error: Unexpected 'string'
   --> namer.test.w:28:6
   |
28 | test "create a file name" {
   |      ^^^^^^^^^^^^^^^^^^^^

error: Unexpected 'variable_definition_statement'
   --> namer.test.w:29:3
   |
29 |   let response = namer.makeFileName("this is the content i want to use to create a file name");
   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: Unexpected 'expression_statement'
   --> namer.test.w:30:3
   |
30 |   log(response);
   |   ^^^^^^^^^^^^^^

error: Unexpected 'reference'
   --> namer.test.w:31:3
   |
31 |   expect.equal(response, {"mock":{"max_tokens":2048,"model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
   |   ^^^^^^^^^^^^

error: Unexpected 'positional_argument'
   --> namer.test.w:31:16
   |
31 |   expect.equal(response, {"mock":{"max_tokens":2048,"model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
   |                ^^^^^^^^

error: Unexpected 'string'
   --> namer.test.w:31:27
   |
31 |   expect.equal(response, {"mock":{"max_tokens":2048,"model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
   |                           ^^^^^^

error: Unexpected 'json_literal_member'
   --> namer.test.w:31:35
   |
31 |   expect.equal(response, {"mock":{"max_tokens":2048,"model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
   |                                   ^^^^^^^^^^^^^^^^^

error: Unexpected 'json_literal_member'
   --> namer.test.w:31:53
   |
31 |   expect.equal(response, {"mock":{"max_tokens":2048,"model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
   |                                                     ^^^^^^^^^^^^^^^^

error: Unexpected 'string'
   --> namer.test.w:31:70
   |
31 |   expect.equal(response, {"mock":{"max_tokens":2048,"model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
   |                                                                      ^^^^^^^^^^

error: Unexpected 'json_literal_member'
   --> namer.test.w:31:83
   |
31 |   expect.equal(response, {"mock":{"max_tokens":2048,"model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
   |                                                                                   ^^^^^^^^^^^^^

error: Unexpected 'string'
   --> namer.test.w:31:97
   |
31 |   expect.equal(response, {"mock":{"max_tokens":2048,"model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
   |                                                                                                 ^^^^^^^^^

error: Unexpected 'ERROR'
   --> namer.test.w:31:109
   |
31 |   expect.equal(response, {"mock":{"max_tokens":2048,"model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
   |                                                                                                             ^

error: Unexpected 'template_substitution'
   --> namer.test.w:31:127
   |
31 |   expect.equal(response, {"mock":{"max_tokens":2048,"model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
   |                                                                                                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: Unknown parser error
   --> namer.test.w:31:128
   |
31 |   expect.equal(response, {"mock":{"max_tokens":2048,"model":"gpt-4o","messages":[{"role":"user","content":"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
   |                                                                                                                                ^

I expected this:

No response

Is there a workaround?

No response

Anything else?

No response

Wing Version

No response

Node.js Version

No response

Platform(s)

No response

Community Notes

MarkMcCulloh commented 1 month ago

The issue here is some unescaped {s and }s on the second to last line. Using the newish uninterpolated string, this parsed correctly with the addition of a #

bring "./namer.w" as n;
bring cloud;
bring openai;

let oaik = new cloud.Secret(name: "OPENAI_KEY") as "openai_key";
let model = new openai.OpenAI(apiKeySecret: oaik) as "gpt_4o";

let namer = new n.Namer(model: model);

let examples = [
  "this is the content i want to use to create a file name",
  "this is another content i want to use to create a file name",
  "this is a third content i want to use to create a file name",
  "a poem about the ocean",
  "a poem about the sky",
  "some big string: 1234567890!@#$%^&*()_+",
];

new cloud.Function(inflight () => {
  for e in examples {
    let name = namer.makeFileName(e);
    log(name);
  }
});

bring expect;
test "create a file name" {
  let response = namer.makeFileName("this is the content i want to use to create a file name");

  expect.equal(response, {
    "mock":{
      "max_tokens":2048,
      "model":"gpt-4o","messages":[{"role":"user","content":#"{\"make_filename\":{\"content\":\"this is the content i want to use to create a file name\",\"all_lowercase\":true,\"word_delimiter\":\"-\",\"ext\":\".txt\",\"output_min_length\":5,\"output_max_length\":20,\"output_allowed_chars\":\"a-z0-9-\"},\"output_instructions\":\"output only the file name itself with the .txt extension without any surrounding quotes or other characters\"}"}]}});
}

Unfortunetly since we use tree-sitter for parsing we are limited in what kind of auto-detection of this issue we can feasibly have. For this example specifically it may be useful to create Json literal and stringify it as needed.