Repository: syuilo/aiscript
Pull request #286 (2023-07-07 19:56:14)

or/andの結果が第一引数で確定する時、第二引数を評価しないようにする
solve #281

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/syuilo/aiscript/pull/286?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=syuilo) Report
Patch coverage: **`100.00`**% and project coverage change: **`+0.07`** :tada:
> Comparison is base [(`556e3be`)](https://app.codecov.io/gh/syuilo/aiscript/commit/556e3be3d963baa0696782076771d8c025d7783a?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=syuilo) 88.92% compared to head [(`74c71b5`)](https://app.codecov.io/gh/syuilo/aiscript/pull/286?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=syuilo) 89.00%.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master     #286      +/-   ##
==========================================
+ Coverage   88.92%   89.00%   +0.07%     
==========================================
  Files          19       19              
  Lines        2926     2928       +2     
  Branches      504      507       +3     
==========================================
+ Hits         2602     2606       +4     
+ Misses        314      312       -2     
  Partials       10       10              
```


| [Impacted Files](https://app.codecov.io/gh/syuilo/aiscript/pull/286?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=syuilo) | Coverage Δ | |
|---|---|---|
| [src/interpreter/lib/std.ts](https://app.codecov.io/gh/syuilo/aiscript/pull/286?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=syuilo#diff-c3JjL2ludGVycHJldGVyL2xpYi9zdGQudHM=) | `81.66% <100.00%> (+0.08%)` | :arrow_up: |

... and [1 file with indirect coverage changes](https://app.codecov.io/gh/syuilo/aiscript/pull/286/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=syuilo)


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/syuilo/aiscript/pull/286?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=syuilo).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=syuilo).


Patch:
diff --git a/src/interpreter/lib/std.ts b/src/interpreter/lib/std.ts
index cfb70ac..ac9623b 100644
--- a/src/interpreter/lib/std.ts
+++ b/src/interpreter/lib/std.ts
@@ -33,14 +33,16 @@ export const std: Record<string, Value> = {
 
 	'Core:and': FN_NATIVE(([a, b]) => {
 		assertBoolean(a);
+		if (!a.value) return FALSE;
 		assertBoolean(b);
-		return (a.value && b.value) ? TRUE : FALSE;
+		return b.value ? TRUE : FALSE;
 	}),
 
 	'Core:or': FN_NATIVE(([a, b]) => {
 		assertBoolean(a);
+		if (a.value) return TRUE;
 		assertBoolean(b);
-		return (a.value || b.value) ? TRUE : FALSE;
+		return b.value ? TRUE : FALSE;
 	}),
 
 	'Core:add': FN_NATIVE(([a, b]) => {


Test patch:
diff --git a/test/index.ts b/test/index.ts
index d99c679..049d1f2 100644
--- a/test/index.ts
+++ b/test/index.ts
@@ -6,6 +6,7 @@
 import * as assert from 'assert';
 import { Parser, Interpreter, utils, errors, Ast } from '../src';
 import { NUM, STR, NULL, ARR, OBJ, BOOL, TRUE, FALSE } from '../src/interpreter/value';
+import { RuntimeError } from '../src/error';
 
 const exe = (program: string): Promise<any> => new Promise((ok, err) => {
 	const aiscript = new Interpreter({}, {
@@ -86,6 +87,14 @@ describe('ops', () => {
 		eq(await exe('<: (true && false)'), BOOL(false));
 		eq(await exe('<: (false && true)'), BOOL(false));
 		eq(await exe('<: (false && false)'), BOOL(false));
+		eq(await exe('<: (false && null)'), BOOL(false));
+		try {
+			await exe('<: (true && null)');
+		} catch (e) {
+			if (!(e instanceof RuntimeError)) assert.fail();
+			return;
+		}
+		assert.fail();
 	});
 
 	test.concurrent('||', async () => {
@@ -93,6 +102,14 @@ describe('ops', () => {
 		eq(await exe('<: (true || false)'), BOOL(true));
 		eq(await exe('<: (false || true)'), BOOL(true));
 		eq(await exe('<: (false || false)'), BOOL(false));
+		eq(await exe('<: (true || null)'), BOOL(true));
+		try {
+			await exe('<: (false || null)');
+		} catch (e) {
+			if (!(e instanceof RuntimeError)) assert.fail();
+			return;
+		}
+		assert.fail();
 	});
 
 	test.concurrent('+', async () => {