From 1d3b6848899e3e6bd9a3e474640131fb8677f205 Mon Sep 17 00:00:00 2001 From: John Chen Date: Mon, 23 Jan 2023 14:03:57 -0600 Subject: [PATCH 1/8] Optimization on `gt`, `gte`, `lt`, `lte` --- .../src/main/coffee/engine/prim/prims.coffee | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/engine/src/main/coffee/engine/prim/prims.coffee b/engine/src/main/coffee/engine/prim/prims.coffee index 7237a6875..39fabe2c4 100644 --- a/engine/src/main/coffee/engine/prim/prims.coffee +++ b/engine/src/main/coffee/engine/prim/prims.coffee @@ -142,7 +142,7 @@ module.exports = # (Any, Any) => Boolean gt: (a, b) -> - if (checks.isString(a) and checks.isString(b)) or (checks.isNumber(a) and checks.isNumber(b)) + if (checks.isNumber(a) and checks.isNumber(b)) or (checks.isString(a) and checks.isString(b)) a > b else if typeof(a) is typeof(b) and a.compare? and b.compare? a.compare(b) is GT @@ -151,7 +151,13 @@ module.exports = # (Any, Any) => Boolean gte: (a, b) -> - @gt(a, b) or @equality(a, b) + if (checks.isNumber(a) and checks.isNumber(b)) or (checks.isString(a) and checks.isString(b)) + a >= b + else if typeof(a) is typeof(b) and a.compare? and b.compare? + result = a.compare(b) + result is GT or result is EQ + else + throw exceptions.internal("Invalid operands to `gt`") # [T <: (Array[Link]|Link|AbstractAgentSet[Link])] @ (T*) => LinkSet linkSet: (inputs) -> @@ -159,7 +165,7 @@ module.exports = # (Any, Any) => Boolean lt: (a, b) -> - if (checks.isString(a) and checks.isString(b)) or (checks.isNumber(a) and checks.isNumber(b)) + if (checks.isNumber(a) and checks.isNumber(b)) or (checks.isString(a) and checks.isString(b)) a < b else if typeof(a) is typeof(b) and a.compare? and b.compare? a.compare(b) is LT @@ -168,7 +174,13 @@ module.exports = # (Any, Any) => Boolean lte: (a, b) -> - @lt(a, b) or @equality(a, b) + if (checks.isNumber(a) and checks.isNumber(b)) or (checks.isString(a) and checks.isString(b)) + a <= b + else if typeof(a) is typeof(b) and a.compare? and b.compare? + result = a.compare(b) + result is LT or result is EQ + else + throw exceptions.internal("Invalid operands to `lt`") # Some complications here.... # From 7d17e752cd695ff0710851b434ec9ca6f3a96bcc Mon Sep 17 00:00:00 2001 From: John Chen Date: Sun, 22 Jan 2023 20:25:09 -0600 Subject: [PATCH 2/8] Minor optimization to reduce call layers --- engine/src/main/coffee/engine/core/turtle.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/main/coffee/engine/core/turtle.coffee b/engine/src/main/coffee/engine/core/turtle.coffee index ea518f990..b0793e182 100644 --- a/engine/src/main/coffee/engine/core/turtle.coffee +++ b/engine/src/main/coffee/engine/core/turtle.coffee @@ -160,11 +160,11 @@ module.exports = # (Number, Number) => Agent patchLeftAndAhead: (angle, distance) -> - @patchRightAndAhead(-angle, distance) + @patchAtHeadingAndDistance(@_heading - angle, distance) # (Number) => Agent patchAhead: (distance) -> - @patchRightAndAhead(0, distance) + @patchAtHeadingAndDistance(@_heading, distance) # (() => Any) => Unit ask: (f) -> From b079bbf284e45bb028f25e5fdd9177cf089b8d4f Mon Sep 17 00:00:00 2001 From: John Chen Date: Wed, 14 Sep 2022 13:16:06 -0500 Subject: [PATCH 3/8] zh-cn support for NLW --- .../src/main/coffee/engine/workspace.coffee | 1 + .../src/main/coffee/i18n/i18n-bundle.coffee | 6 + engine/src/main/coffee/i18n/zh_cn.coffee | 174 ++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 engine/src/main/coffee/i18n/zh_cn.coffee diff --git a/engine/src/main/coffee/engine/workspace.coffee b/engine/src/main/coffee/engine/workspace.coffee index c405d3677..f616faf80 100644 --- a/engine/src/main/coffee/engine/workspace.coffee +++ b/engine/src/main/coffee/engine/workspace.coffee @@ -170,4 +170,5 @@ module.exports = updater userDialogPrims world + i18nBundle } diff --git a/engine/src/main/coffee/i18n/i18n-bundle.coffee b/engine/src/main/coffee/i18n/i18n-bundle.coffee index 1dbf2b77d..90394a1aa 100644 --- a/engine/src/main/coffee/i18n/i18n-bundle.coffee +++ b/engine/src/main/coffee/i18n/i18n-bundle.coffee @@ -25,5 +25,11 @@ class I18nBundle message = bundle[key] message(args...) + + switch: (locale) -> + try + @_current = require('i18n/' + locale) + catch + @_current = EN_US module.exports = I18nBundle diff --git a/engine/src/main/coffee/i18n/zh_cn.coffee b/engine/src/main/coffee/i18n/zh_cn.coffee new file mode 100644 index 000000000..e9ad4f328 --- /dev/null +++ b/engine/src/main/coffee/i18n/zh_cn.coffee @@ -0,0 +1,174 @@ +# (C) Uri Wilensky. https://github.com/NetLogo/Tortoise + +bundle = { + + # Math Prims + + 'atan is undefined when both inputs are zero.': () -> + "当两个输入值都为 0 时,atan 函数没有定义。" + + , '_ isn_t a valid base for a logarithm.': (b) -> + "#{b} 不是一个有效的对数底数。" + + , 'The square root of _ is an imaginary number.': (n) -> + "值 #{n} 的平方根是虚数,无法运算。" + + , 'math operation produced a non-number': () -> + "数学运算产生了一个非数字。" + + , 'math operation produced a number too large for NetLogo': () -> + "数学运算产生了一个对 NetLogo 来说过大的数字。" + + , 'Division by zero.': () -> + "被零除(的结果不存在)。" + + , 'Can_t take logarithm of _.': (n) -> + "无法为值 #{n} 取对数。" + + # Color Prims + + , 'Color must be a number or a valid RGB/A color list with 3 - 4 numbers that have values between 0 and 255.': () -> + 'Color must be a number or a valid RGB/A color list with 3 - 4 numbers that have values between 0 and 255.' + + # Other Prims + + , 'random-normal_s second input can_t be negative.': () -> + "random-normal's second input can't be negative." + + , 'Both Inputs to RANDOM-GAMMA must be positive.': () -> + "Both Inputs to RANDOM-GAMMA must be positive." + + , '_ is not in the allowable range for random seeds (-2147483648 to 2147483647)': (n) -> + "#{n} is not in the allowable range for random seeds (-2147483648 to 2147483647)" + + , '_ is too large to be represented exactly as an integer in NetLogo': (n) -> + "#{n} is too large to be represented exactly as an integer in NetLogo" + + , 'List is empty.': () -> + "List is empty." + + , 'Can_t find element _ of the _ _, which is only of length _.': (n, type, list, length) -> + "Can't find element #{n} of the #{type} #{list}, which is only of length #{length}." + + , 'The list argument to reduce must not be empty.': () -> + "The list argument to reduce must not be empty." + + , '_ is greater than the length of the input list (_).': (endIndex, listLength) -> + "#{endIndex} is greater than the length of the input list (#{listLength})." + + , '_ is less than zero.': (index) -> + "#{index} is less than zero." + + , '_ is less than _.': (endIndex, startIndex) -> + "#{endIndex} is less than #{startIndex}." + + , '_ got an empty _ as input.': (prim, type) -> + "#{prim} got an empty #{type} as input." + + , '_ isn_t greater than or equal to zero.': (index) -> + "#{index} isn't greater than or equal to zero." + + , 'Can_t find the _ of a list with no numbers: __': (aspect, list, punc) -> + "Can't find the #{aspect} of a list with no numbers: #{list}#{punc}" + + , 'Requested _ random items from a list of length _.': (count, length) -> + "Requested #{count} random items from a list of length #{length}." + + , 'Requested _ random agents from a set of only _ agents.': (count, size) -> + "Requested #{count} random agents from a set of only #{size} agents." + + , 'Can_t find the _ of a list without at least two numbers: __': (aspect, list, punc) -> + "Can't find the #{aspect} of a list without at least two numbers: #{list}#{punc}" + + , 'Invalid list of points: _': (points) -> + "Invalid list of points: #{points}" + + , 'Requested _ random agents from a set of only _ agents.': (n, size) -> + "Requested #{n} random agents from a set of only #{size} agents." + + , 'First input to _ can_t be negative.': (prim) -> + "First input to #{prim} can't be negative." + + , '_ expected a true/false value from _, but got _ instead.': (prim, item, value) -> + "#{prim} expected a true/false value from #{item}, but got #{value} instead." + + , '_ expected input to be a _ agentset or _ but got _ instead.': (prim, agentType, value) -> + "#{prim} expected input to be a #{agentType} agentset or #{agentType} but got #{value} instead." + + , '_ expected input to be _ but got _ instead.': (prim, expectedType, actualType) -> + "#{prim} expected input to be #{expectedType} but got #{actualType} instead." + + , 'List inputs to _ must only contain _, _ agentset, or list elements. The list _ contained _ which is NOT a _ or _ agentset.': (prim, agentType, list, value) -> + "List inputs to #{prim} must only contain #{agentType}, #{agentType} agentset, or list elements. The list #{list} contained #{value} which is NOT a #{agentType} or #{agentType} agentset." + + , 'List inputs to _ must only contain _, _ agentset, or list elements. The list _ contained a different type agentset: _.': (prim, agentType, list, value) -> + "List inputs to #{prim} must only contain #{agentType}, #{agentType} agentset, or list elements. The list #{list} contained a different type agentset: #{value}." + + , 'SORT-ON works on numbers, strings, or agents of the same type, but not on _ and _': (type1, type2) -> + "SORT-ON works on numbers, strings, or agents of the same type, but not on #{type1} and #{type2}" + + , 'anonymous procedure expected _ input_, but only got _': (needed, given) -> + "anonymous procedure expected #{needed} input#{if needed isnt 1 then "s" else ""}, but only got #{given}" + + , 'REPORT can only be used inside TO-REPORT.': () -> + "REPORT can only be used inside TO-REPORT." + + , 'STOP is not allowed inside TO-REPORT.': () -> + "STOP is not allowed inside TO-REPORT." + + , 'Reached end of reporter procedure without REPORT being called.': () -> + "Reached end of reporter procedure without REPORT being called." + + , '_ doesn_t accept further inputs if the first is a string': (primName) -> + "#{primName} doesn't accept further inputs if the first is a string" + + , 'Unfortunately, no perfect equivalent to `_` can be implemented in NetLogo Web. However, the \'import-a\' and \'fetch\' extensions offer primitives that can accomplish this in both NetLogo and NetLogo Web.': (primName) -> + "Unfortunately, no perfect equivalent to `#{primName}` can be implemented in NetLogo Web. However, the \'import-a\' and \'fetch\' extensions offer primitives that can accomplish this in both NetLogo and NetLogo Web." + + , 'The point [ _ , _ ] is outside of the boundaries of the world and wrapping is not permitted in one or both directions.': (x, y) -> + "The point [ #{x} , #{y} ] is outside of the boundaries of the world and wrapping is not permitted in one or both directions." + + , 'Cannot move turtle beyond the world_s edge.': () -> + "Cannot move turtle beyond the world's edge." + + , 'there is no heading of a link whose endpoints are in the same position': () -> + "there is no heading of a link whose endpoints are in the same position" + + , 'No heading is defined from a point (_,_) to that same point.': (x, y) -> + "No heading is defined from a point (#{x},#{y}) to that same point." + + , '_ is not an integer': (x) -> + "#{x} is not an integer" + + , '_ is not a _': (breed1, breed2) -> + "#{breed1} is not a #{breed2}" + + , 'An rgb list must contain 3 numbers 0-255': -> + 'An rgb list must contain 3 numbers 0-255' + + , 'An rgb list must contain 3 or 4 numbers 0-255': -> + 'An rgb list must contain 3 or 4 numbers 0-255' + + , 'RGB values must be 0-255': -> + 'RGB values must be 0-255' + + , "can't set _ variable _ to non-number _": (e) -> + "can't set #{e.myType} variable #{e.varName.toUpperCase()} to non-number #{e.target}" + + , '_ breed does not own variable _': (breedName, varName) -> + "#{breedName} breed does not own variable #{varName}" + + , 'All the list arguments to _ must be the same length.': (primName) -> + "All the list arguments to #{primName} must be the same length." + + , 'The step-size for range must be non-zero.': () -> + "The step-size for range must be non-zero." + + , 'range expects at most three arguments': () -> + "range expects at most three arguments" + + , '_ cannot take a negative number.': (primName) -> + "#{primName} cannot take a negative number." +} + +module.exports = bundle From 314cf8e07ff7534d2023a34a72f0cf8a25289ffd Mon Sep 17 00:00:00 2001 From: John Chen Date: Wed, 14 Sep 2022 18:56:41 -0500 Subject: [PATCH 4/8] i18n + others --- .../engine/prim-checks/validator.coffee | 4 +- engine/src/main/coffee/i18n/en_us.coffee | 7 +- engine/src/main/coffee/i18n/zh_cn.coffee | 99 ++++++++++--------- engine/src/main/coffee/util/exception.coffee | 2 +- 4 files changed, 57 insertions(+), 55 deletions(-) diff --git a/engine/src/main/coffee/engine/prim-checks/validator.coffee b/engine/src/main/coffee/engine/prim-checks/validator.coffee index 8a1ce0ef8..0beb441b7 100644 --- a/engine/src/main/coffee/engine/prim-checks/validator.coffee +++ b/engine/src/main/coffee/engine/prim-checks/validator.coffee @@ -35,7 +35,7 @@ class Validator # (String, Int | null, Int | null, String, Array[Any]) => Unit error: (prim, sourceStart, sourceEnd, messageKey, messageValues...) -> message = @bundle.get(messageKey, messageValues.map( (val) -> if typeof(val) is "function" then val() else val )...) - throw exceptions.runtime(message, prim, maybe(sourceStart), maybe(sourceEnd)) + throw exceptions.runtime(message, prim, maybe(sourceStart), maybe(sourceEnd), messageKey) # (String, Int, Int, Number) => Number checkLong: (prim, sourceStart, sourceEnd, value) -> @@ -86,7 +86,7 @@ class Validator # (String, Int, Int, Any, Array[NLType]) => Unit throwTypeError: (prim, sourceStart, SourceEnd, value, expectedTypes...) -> - throw exceptions.runtime(@typeError(prim, value, expectedTypes), prim, maybe(sourceStart), maybe(SourceEnd)) + throw exceptions.runtime(@typeError(prim, value, expectedTypes), prim, maybe(sourceStart), maybe(SourceEnd), "_ expected input to be _ but got _ instead.") return # (Array[Array[NLType]]) => (String, Array[Any]) => Unit diff --git a/engine/src/main/coffee/i18n/en_us.coffee b/engine/src/main/coffee/i18n/en_us.coffee index decaf7a76..b623d0ba9 100644 --- a/engine/src/main/coffee/i18n/en_us.coffee +++ b/engine/src/main/coffee/i18n/en_us.coffee @@ -83,9 +83,6 @@ bundle = { , 'Invalid list of points: _': (points) -> "Invalid list of points: #{points}" - , 'Requested _ random agents from a set of only _ agents.': (n, size) -> - "Requested #{n} random agents from a set of only #{size} agents." - , 'First input to _ can_t be negative.': (prim) -> "First input to #{prim} can't be negative." @@ -169,6 +166,10 @@ bundle = { , '_ cannot take a negative number.': (primName) -> "#{primName} cannot take a negative number." + + # Dynamic Calls (TU) + , 'Cannot find the procedure _.': (procedureName) -> + "Cannot find the procedure #{procedureName}." } module.exports = bundle diff --git a/engine/src/main/coffee/i18n/zh_cn.coffee b/engine/src/main/coffee/i18n/zh_cn.coffee index e9ad4f328..81ef85fd1 100644 --- a/engine/src/main/coffee/i18n/zh_cn.coffee +++ b/engine/src/main/coffee/i18n/zh_cn.coffee @@ -28,147 +28,148 @@ bundle = { # Color Prims , 'Color must be a number or a valid RGB/A color list with 3 - 4 numbers that have values between 0 and 255.': () -> - 'Color must be a number or a valid RGB/A color list with 3 - 4 numbers that have values between 0 and 255.' + '颜色必须是一个 RGB 颜色列表,其中包含 3-4 个 0-255 之间的数字。' # Other Prims , 'random-normal_s second input can_t be negative.': () -> - "random-normal's second input can't be negative." + "random-normal 的第二个输入不能为负。" , 'Both Inputs to RANDOM-GAMMA must be positive.': () -> - "Both Inputs to RANDOM-GAMMA must be positive." + "RANDOM-GAMMA 的两个输入都必须为正。" , '_ is not in the allowable range for random seeds (-2147483648 to 2147483647)': (n) -> - "#{n} is not in the allowable range for random seeds (-2147483648 to 2147483647)" + "#{n} 不在随机数种子的可接受范围内 (-2147483648 ~ 2147483647)" , '_ is too large to be represented exactly as an integer in NetLogo': (n) -> - "#{n} is too large to be represented exactly as an integer in NetLogo" + "#{n} 太大了,无法在 NetLogo 中以整数形式表达。" , 'List is empty.': () -> - "List is empty." + "列表为空。" , 'Can_t find element _ of the _ _, which is only of length _.': (n, type, list, length) -> - "Can't find element #{n} of the #{type} #{list}, which is only of length #{length}." + "找不到 #{type} #{list} 的第 #{n} 个成员,因为列表的长度只有 #{length}。" , 'The list argument to reduce must not be empty.': () -> - "The list argument to reduce must not be empty." + "用于 reduce 的列表参数不能为空。" , '_ is greater than the length of the input list (_).': (endIndex, listLength) -> - "#{endIndex} is greater than the length of the input list (#{listLength})." + "#{endIndex} 大于输入列表的长度 (#{listLength})。" , '_ is less than zero.': (index) -> - "#{index} is less than zero." + "#{index} 小于 0。" , '_ is less than _.': (endIndex, startIndex) -> - "#{endIndex} is less than #{startIndex}." + "#{endIndex} 小于 #{startIndex}。" , '_ got an empty _ as input.': (prim, type) -> - "#{prim} got an empty #{type} as input." + "#{prim} 的 #{type} 输入为空。" , '_ isn_t greater than or equal to zero.': (index) -> - "#{index} isn't greater than or equal to zero." + "#{index} 需要大于或等于 0。" , 'Can_t find the _ of a list with no numbers: __': (aspect, list, punc) -> - "Can't find the #{aspect} of a list with no numbers: #{list}#{punc}" + "在不存在数字的列表 #{list}#{punc} 中找不到 #{aspect}。" , 'Requested _ random items from a list of length _.': (count, length) -> - "Requested #{count} random items from a list of length #{length}." + "无法从一个长度为 #{length} 的列表中取出 #{count} 个随机项。" , 'Requested _ random agents from a set of only _ agents.': (count, size) -> - "Requested #{count} random agents from a set of only #{size} agents." + "无法从一个只有 #{size} 项的主体集合中取出 #{count} 个随机主体。" , 'Can_t find the _ of a list without at least two numbers: __': (aspect, list, punc) -> - "Can't find the #{aspect} of a list without at least two numbers: #{list}#{punc}" + "#{list}#{punc} 中至少需要两个数字,才能用来找到 #{aspect}。" , 'Invalid list of points: _': (points) -> - "Invalid list of points: #{points}" - - , 'Requested _ random agents from a set of only _ agents.': (n, size) -> - "Requested #{n} random agents from a set of only #{size} agents." + "坐标列表 #{points} 无效。" , 'First input to _ can_t be negative.': (prim) -> - "First input to #{prim} can't be negative." + "#{prim} 的第一个输入不能为负。" , '_ expected a true/false value from _, but got _ instead.': (prim, item, value) -> - "#{prim} expected a true/false value from #{item}, but got #{value} instead." + "#{prim} 希望从 #{item} 中得到 true/false 值,得到的却是 #{value}。" , '_ expected input to be a _ agentset or _ but got _ instead.': (prim, agentType, value) -> - "#{prim} expected input to be a #{agentType} agentset or #{agentType} but got #{value} instead." + "#{prim} 的输入应为 #{agentType} 或其集合,得到的却是 #{value}。" , '_ expected input to be _ but got _ instead.': (prim, expectedType, actualType) -> - "#{prim} expected input to be #{expectedType} but got #{actualType} instead." + "#{prim} 的输入应为 #{expectedType},得到的却是 #{actualType}。" , 'List inputs to _ must only contain _, _ agentset, or list elements. The list _ contained _ which is NOT a _ or _ agentset.': (prim, agentType, list, value) -> - "List inputs to #{prim} must only contain #{agentType}, #{agentType} agentset, or list elements. The list #{list} contained #{value} which is NOT a #{agentType} or #{agentType} agentset." + "#{prim} 的列表输入只能包含其它列表、#{agentType}、或 #{agentType} 的集合。但是,列表 #{list} 中的值 #{value} 不属于上述类别。" , 'List inputs to _ must only contain _, _ agentset, or list elements. The list _ contained a different type agentset: _.': (prim, agentType, list, value) -> - "List inputs to #{prim} must only contain #{agentType}, #{agentType} agentset, or list elements. The list #{list} contained a different type agentset: #{value}." + "#{prim} 的列表输入只能包含其它列表、#{agentType}、或 #{agentType} 的集合。但是,列表 #{list} 包括了不同种类的主体集合: #{value}。" , 'SORT-ON works on numbers, strings, or agents of the same type, but not on _ and _': (type1, type2) -> - "SORT-ON works on numbers, strings, or agents of the same type, but not on #{type1} and #{type2}" + "SORT-ON 可以用于数字、字符串或同类型的主体,但不能用于 #{type1} 或 #{type2}。" , 'anonymous procedure expected _ input_, but only got _': (needed, given) -> - "anonymous procedure expected #{needed} input#{if needed isnt 1 then "s" else ""}, but only got #{given}" + "匿名函数需要 #{needed} 个输入,得到的却只有 #{given} 个。" , 'REPORT can only be used inside TO-REPORT.': () -> - "REPORT can only be used inside TO-REPORT." + "REPORT 只能在 TO-REPORT 中使用。" , 'STOP is not allowed inside TO-REPORT.': () -> - "STOP is not allowed inside TO-REPORT." + "不能在 TO-REPORT 中使用 STOP。" , 'Reached end of reporter procedure without REPORT being called.': () -> - "Reached end of reporter procedure without REPORT being called." + "在函数结束时,应当使用 `REPORT` 进行输出。" , '_ doesn_t accept further inputs if the first is a string': (primName) -> - "#{primName} doesn't accept further inputs if the first is a string" + "如果第一个输入是字符串,#{primName} 无法接受更多输入。" , 'Unfortunately, no perfect equivalent to `_` can be implemented in NetLogo Web. However, the \'import-a\' and \'fetch\' extensions offer primitives that can accomplish this in both NetLogo and NetLogo Web.': (primName) -> - "Unfortunately, no perfect equivalent to `#{primName}` can be implemented in NetLogo Web. However, the \'import-a\' and \'fetch\' extensions offer primitives that can accomplish this in both NetLogo and NetLogo Web." + "抱歉,海龟实验室中无法实现 `#{primName}`。不过,例如 `import-a` 和 `fetch` 这样的扩展可以实现你需要的功能。" , 'The point [ _ , _ ] is outside of the boundaries of the world and wrapping is not permitted in one or both directions.': (x, y) -> - "The point [ #{x} , #{y} ] is outside of the boundaries of the world and wrapping is not permitted in one or both directions." + "坐标 [ #{x} , #{y} ] 位于世界边缘之外,并且相应方向的世界环绕没有启用。" , 'Cannot move turtle beyond the world_s edge.': () -> - "Cannot move turtle beyond the world's edge." + "无法将海龟移动到世界边缘之外。" , 'there is no heading of a link whose endpoints are in the same position': () -> - "there is no heading of a link whose endpoints are in the same position" + "两个端点位置相同的链接不存在朝向角度。" , 'No heading is defined from a point (_,_) to that same point.': (x, y) -> - "No heading is defined from a point (#{x},#{y}) to that same point." + "从 (#{x},#{y}) 到同一个位置之间不存在朝向角度。" , '_ is not an integer': (x) -> - "#{x} is not an integer" + "#{x} 不是整数。" , '_ is not a _': (breed1, breed2) -> - "#{breed1} is not a #{breed2}" + "#{breed1} 不是 #{breed2}。" , 'An rgb list must contain 3 numbers 0-255': -> - 'An rgb list must contain 3 numbers 0-255' + '一个 RGB 颜色列表必须包含 3 个 0-255 之间的数字。' , 'An rgb list must contain 3 or 4 numbers 0-255': -> - 'An rgb list must contain 3 or 4 numbers 0-255' + '一个 RGB 颜色列表必须包含 3-4 个 0-255 之间的数字。' , 'RGB values must be 0-255': -> - 'RGB values must be 0-255' + 'RGB 值必须介于 0-255 之间。' , "can't set _ variable _ to non-number _": (e) -> - "can't set #{e.myType} variable #{e.varName.toUpperCase()} to non-number #{e.target}" + "无法将 #{e.myType} 类型的变量 #{e.varName.toUpperCase()} 设置为非数字 #{e.target}" , '_ breed does not own variable _': (breedName, varName) -> - "#{breedName} breed does not own variable #{varName}" + "种类 #{breedName} 中并未定义参数 #{varName}" , 'All the list arguments to _ must be the same length.': (primName) -> - "All the list arguments to #{primName} must be the same length." + "#{primName} 的所有列表参数必须长度相同。" , 'The step-size for range must be non-zero.': () -> - "The step-size for range must be non-zero." + "区间的步进大小不能为零。" , 'range expects at most three arguments': () -> - "range expects at most three arguments" + "区间最多只接受三个参数。" , '_ cannot take a negative number.': (primName) -> - "#{primName} cannot take a negative number." + "#{primName} 不能取负值。" + + # Dynamic Calls (TU) + , 'Cannot find the procedure _.': (procedureName) -> + "无法找到函数 #{procedureName}." } module.exports = bundle diff --git a/engine/src/main/coffee/util/exception.coffee b/engine/src/main/coffee/util/exception.coffee index b0bd8b7b3..c0340126a 100644 --- a/engine/src/main/coffee/util/exception.coffee +++ b/engine/src/main/coffee/util/exception.coffee @@ -21,7 +21,7 @@ class InternalException extends NetLogoException # Represents typical, expected runtime errors in the engine, like dividing by zero # or using `ask` on nobody, etc. -Jeremy B March 2021 class RuntimeException extends NetLogoException - constructor: (message, @primitive, stackTrace, stackTraceMessage, @sourceStart, @sourceEnd) -> + constructor: (message, @primitive, stackTrace, stackTraceMessage, @sourceStart, @sourceEnd, @messageKey) -> super(message, stackTrace, stackTraceMessage) class ExceptionFactory From 807844efd883fdbc92f839b44119b0b024592454 Mon Sep 17 00:00:00 2001 From: John Chen Date: Mon, 30 Jan 2023 09:59:38 -0600 Subject: [PATCH 5/8] Added comments on Jeremy's request --- engine/src/main/coffee/engine/core/turtle.coffee | 2 ++ engine/src/main/coffee/engine/prim/prims.coffee | 3 +++ 2 files changed, 5 insertions(+) diff --git a/engine/src/main/coffee/engine/core/turtle.coffee b/engine/src/main/coffee/engine/core/turtle.coffee index b0793e182..e2aeef92e 100644 --- a/engine/src/main/coffee/engine/core/turtle.coffee +++ b/engine/src/main/coffee/engine/core/turtle.coffee @@ -159,6 +159,8 @@ module.exports = @patchAtHeadingAndDistance(@_heading + angle, distance) # (Number, Number) => Agent + # One might ask: why don't you use patchRightAndAhead here? The answer again: to reduce unnecessary function calls for frequently called prims. + # In this case, removing the addition call does not add difficulty to maintenance; although the performance boost is supposed to be little as well. patchLeftAndAhead: (angle, distance) -> @patchAtHeadingAndDistance(@_heading - angle, distance) diff --git a/engine/src/main/coffee/engine/prim/prims.coffee b/engine/src/main/coffee/engine/prim/prims.coffee index 39fabe2c4..f09a98648 100644 --- a/engine/src/main/coffee/engine/prim/prims.coffee +++ b/engine/src/main/coffee/engine/prim/prims.coffee @@ -173,6 +173,9 @@ module.exports = throw exceptions.internal("Invalid operands to `lt`") # (Any, Any) => Boolean + # Why don't we simply use lt + eq (and in gte's case, gt + eq?) Because it will cause many unnecessary type checks. + # In many cases, the goal for those prims - very frequently executed by NL code - is not to keep short, but rather to achieve the best performance, + # even if it means additional amount of code. --JC (01/30/23) lte: (a, b) -> if (checks.isNumber(a) and checks.isNumber(b)) or (checks.isString(a) and checks.isString(b)) a <= b From 8f7203779cdc9641fa7fc2e41c7b93c69dbfed31 Mon Sep 17 00:00:00 2001 From: John Chen Date: Mon, 30 Jan 2023 13:37:42 -0600 Subject: [PATCH 6/8] Appeasing the linter --- engine/src/main/coffee/engine/core/turtle.coffee | 1 + engine/src/main/coffee/engine/prim/prims.coffee | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/src/main/coffee/engine/core/turtle.coffee b/engine/src/main/coffee/engine/core/turtle.coffee index e2aeef92e..46aab12b9 100644 --- a/engine/src/main/coffee/engine/core/turtle.coffee +++ b/engine/src/main/coffee/engine/core/turtle.coffee @@ -161,6 +161,7 @@ module.exports = # (Number, Number) => Agent # One might ask: why don't you use patchRightAndAhead here? The answer again: to reduce unnecessary function calls for frequently called prims. # In this case, removing the addition call does not add difficulty to maintenance; although the performance boost is supposed to be little as well. + # -JC (1/30/23) patchLeftAndAhead: (angle, distance) -> @patchAtHeadingAndDistance(@_heading - angle, distance) diff --git a/engine/src/main/coffee/engine/prim/prims.coffee b/engine/src/main/coffee/engine/prim/prims.coffee index f09a98648..2deb43502 100644 --- a/engine/src/main/coffee/engine/prim/prims.coffee +++ b/engine/src/main/coffee/engine/prim/prims.coffee @@ -173,7 +173,7 @@ module.exports = throw exceptions.internal("Invalid operands to `lt`") # (Any, Any) => Boolean - # Why don't we simply use lt + eq (and in gte's case, gt + eq?) Because it will cause many unnecessary type checks. + # Why don't we simply use lt + eq (and in gte's case, gt + eq?) Because it will cause many unnecessary type checks. # In many cases, the goal for those prims - very frequently executed by NL code - is not to keep short, but rather to achieve the best performance, # even if it means additional amount of code. --JC (01/30/23) lte: (a, b) -> From 9f11afd71eedee75fc4c2e9b19d7e0ba68ab97a6 Mon Sep 17 00:00:00 2001 From: John Chen Date: Sat, 11 Feb 2023 12:52:58 -0600 Subject: [PATCH 7/8] Jeremy's request --- engine/src/main/coffee/util/exception.coffee | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/engine/src/main/coffee/util/exception.coffee b/engine/src/main/coffee/util/exception.coffee index c0340126a..637c78ae8 100644 --- a/engine/src/main/coffee/util/exception.coffee +++ b/engine/src/main/coffee/util/exception.coffee @@ -73,10 +73,12 @@ class ExceptionFactory new InternalException(message, stackFrames, stackTraceMessage) # (String, String, Maybe[Int], Maybe[Int]) => RuntimeException - runtime: (message, primitive, sourceStart = None, sourceEnd = None) -> + # Most of the existing call to this function have not been changed to i18n + messageKey. + # They should be gradually switched to validator.error(). - JC 02/11/23 + runtime: (message, primitive, sourceStart = None, sourceEnd = None, messageKey = None) -> stackFrames = @getStackTrace() stackTraceMessage = @makeStackTraceMessage(stackFrames, primitive) - new RuntimeException(message, primitive, stackFrames, stackTraceMessage, sourceStart, sourceEnd) + new RuntimeException(message, primitive, stackFrames, stackTraceMessage, sourceStart, sourceEnd, messageKey) factory = new ExceptionFactory() From d9484a81f302521fb561f1a499e00444831342eb Mon Sep 17 00:00:00 2001 From: John Chen Date: Tue, 14 Feb 2023 11:15:06 -0600 Subject: [PATCH 8/8] Appeasing the linter by removing trailing whitespaces. --- engine/src/main/coffee/util/exception.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/coffee/util/exception.coffee b/engine/src/main/coffee/util/exception.coffee index 637c78ae8..a38d73a98 100644 --- a/engine/src/main/coffee/util/exception.coffee +++ b/engine/src/main/coffee/util/exception.coffee @@ -73,7 +73,7 @@ class ExceptionFactory new InternalException(message, stackFrames, stackTraceMessage) # (String, String, Maybe[Int], Maybe[Int]) => RuntimeException - # Most of the existing call to this function have not been changed to i18n + messageKey. + # Most of the existing call to this function have not been changed to i18n + messageKey. # They should be gradually switched to validator.error(). - JC 02/11/23 runtime: (message, primitive, sourceStart = None, sourceEnd = None, messageKey = None) -> stackFrames = @getStackTrace()