Syntax highlighting changes
This commit is contained in:
parent
31d30da855
commit
a23147b5c6
4 changed files with 119 additions and 65 deletions
|
|
@ -17,7 +17,7 @@ right_brace: "}"
|
||||||
|
|
||||||
# Build settings
|
# Build settings
|
||||||
|
|
||||||
exclude: ["index.html", "**/index.html", "logs", "node_modules", "**/c64", "src", "**/src", "**/static", "tmp", "videos", "web", ".git", ".idea"]
|
exclude: ["index.html", "**/index.html", "logs", "node_modules", "**/c64", "**/private", "src", "**/src", "**/static", "tmp", "videos", "web", ".git", ".idea"]
|
||||||
markdown: kramdown
|
markdown: kramdown
|
||||||
kramdown:
|
kramdown:
|
||||||
input: GFM
|
input: GFM
|
||||||
|
|
|
||||||
|
|
@ -51,34 +51,42 @@ can be thought of as "class constants".
|
||||||
For example, the ChipSet component, which manages (among other things) Programmable Interrupt Controllers or PICs,
|
For example, the ChipSet component, which manages (among other things) Programmable Interrupt Controllers or PICs,
|
||||||
*could* define the constant for an EOI command like this:
|
*could* define the constant for an EOI command like this:
|
||||||
|
|
||||||
ChipSet.EOI = 0x20; // non-specific EOI (end-of-interrupt)
|
``` javascript
|
||||||
|
ChipSet.EOI = 0x20; // non-specific EOI (end-of-interrupt)
|
||||||
|
```
|
||||||
|
|
||||||
but since the EOI command is actually one of a number Operation Command Words (specifically, OCW2), I include an
|
but since the EOI command is actually one of a number Operation Command Words (specifically, OCW2), I include an
|
||||||
"OCW2_" prefix in the constant name:
|
"OCW2_" prefix in the constant name:
|
||||||
|
|
||||||
ChipSet.OCW2_EOI = 0x20; // non-specific EOI (end-of-interrupt)
|
``` javascript
|
||||||
|
ChipSet.OCW2_EOI = 0x20; // non-specific EOI (end-of-interrupt)
|
||||||
|
```
|
||||||
|
|
||||||
and since I also like to group constants that are associated with a particular register or port, and since I don't
|
and since I also like to group constants that are associated with a particular register or port, and since I don't
|
||||||
want the ChipSet constructor becoming littered with property constants, I first define a constant object; in this
|
want the ChipSet constructor becoming littered with property constants, I first define a constant object; in this
|
||||||
case, **PIC_LO**:
|
case, **PIC_LO**:
|
||||||
|
|
||||||
ChipSet.PIC_LO = {};
|
``` javascript
|
||||||
ChipSet.PIC_LO.OCW2_EOI = 0x20; // non-specific EOI (end-of-interrupt)
|
ChipSet.PIC_LO = {};
|
||||||
ChipSet.PIC_LO.OCW2_EOI_SPEC = 0x60; // specific EOI
|
ChipSet.PIC_LO.OCW2_EOI = 0x20; // non-specific EOI (end-of-interrupt)
|
||||||
ChipSet.PIC_LO.OCW2_EOI_ROT = 0xA0; // rotate on non-specific EOI
|
ChipSet.PIC_LO.OCW2_EOI_SPEC = 0x60; // specific EOI
|
||||||
ChipSet.PIC_LO.OCW2_EOI_ROTSPEC = 0xE0; // rotate on specific EOI
|
ChipSet.PIC_LO.OCW2_EOI_ROT = 0xA0; // rotate on non-specific EOI
|
||||||
|
ChipSet.PIC_LO.OCW2_EOI_ROTSPEC = 0xE0; // rotate on specific EOI
|
||||||
|
```
|
||||||
|
|
||||||
By using fully-qualified property names for each constant, the code has a more C-like appearance (think *#define*)
|
By using fully-qualified property names for each constant, the code has a more C-like appearance (think *#define*)
|
||||||
that's also easier to preprocess.
|
that's also easier to preprocess.
|
||||||
|
|
||||||
However, I've gradually switched to the more conventional JavaScript object notation for class constants:
|
However, I've gradually switched to the more conventional JavaScript object notation for class constants:
|
||||||
|
|
||||||
ChipSet.PIC_LO = {
|
``` javascript
|
||||||
OCW2_EOI: 0x20, // non-specific EOI (end-of-interrupt)
|
ChipSet.PIC_LO = {
|
||||||
OCW2_EOI_SPEC: 0x60, // specific EOI
|
OCW2_EOI: 0x20, // non-specific EOI (end-of-interrupt)
|
||||||
OCW2_EOI_ROT: 0xA0, // rotate on non-specific EOI
|
OCW2_EOI_SPEC: 0x60, // specific EOI
|
||||||
OCW2_EOI_ROTSPEC: 0xE0 // rotate on specific EOI
|
OCW2_EOI_ROT: 0xA0, // rotate on non-specific EOI
|
||||||
};
|
OCW2_EOI_ROTSPEC: 0xE0 // rotate on specific EOI
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
because, again, the Closure Compiler does an excellent job inlining such constants (or indeed any property that is
|
because, again, the Closure Compiler does an excellent job inlining such constants (or indeed any property that is
|
||||||
never modified *or* enumerated).
|
never modified *or* enumerated).
|
||||||
|
|
@ -94,17 +102,23 @@ override it, setting it to **FALSE** and disabling debug-only code.
|
||||||
|
|
||||||
To ensure that debug-only code is not simply *disabled* but also *removed*, the code should be wrapped with:
|
To ensure that debug-only code is not simply *disabled* but also *removed*, the code should be wrapped with:
|
||||||
|
|
||||||
if (DEBUG) {
|
``` javascript
|
||||||
[code to be removed by the Closure Compiler]
|
if (DEBUG) {
|
||||||
}
|
[code to be removed by the Closure Compiler]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
In many cases, the compiler is able to completely remove calls to debug-only class methods; eg:
|
In many cases, the compiler is able to completely remove calls to debug-only class methods; eg:
|
||||||
|
|
||||||
Component.assert(off >= 0 && off < this.cb);
|
``` javascript
|
||||||
|
Component.assert(off >= 0 && off < this.cb);
|
||||||
|
```
|
||||||
|
|
||||||
However, calls to debug-only instance methods seem to be more problematic, so all such calls are wrapped; eg:
|
However, calls to debug-only instance methods seem to be more problematic, so all such calls are wrapped; eg:
|
||||||
|
|
||||||
if (DEBUG) this.log('load("' + sFileURL + '")');
|
``` javascript
|
||||||
|
if (DEBUG) this.log('load("' + sFileURL + '")');
|
||||||
|
```
|
||||||
|
|
||||||
There are a number of other important shared constants in [/modules/shared/lib/defines.js](/modules/shared/lib/defines.js)
|
There are a number of other important shared constants in [/modules/shared/lib/defines.js](/modules/shared/lib/defines.js)
|
||||||
and PCjs-specific constants in [/modules/pcjs/lib/defines.js](/modules/pcjs/lib/defines.js); refer
|
and PCjs-specific constants in [/modules/pcjs/lib/defines.js](/modules/pcjs/lib/defines.js); refer
|
||||||
|
|
@ -163,12 +177,16 @@ objects, but I'll leave my gripes about JSON for another post.
|
||||||
|
|
||||||
Generally speaking, the only time I quote property names is when I have to. I'll use the "dot" syntax; eg:
|
Generally speaking, the only time I quote property names is when I have to. I'll use the "dot" syntax; eg:
|
||||||
|
|
||||||
obj.prop = true;
|
``` javascript
|
||||||
|
obj.prop = true;
|
||||||
|
```
|
||||||
|
|
||||||
instead of:
|
instead of:
|
||||||
|
|
||||||
obj['prop'] = true;
|
``` javascript
|
||||||
|
obj['prop'] = true;
|
||||||
|
```
|
||||||
|
|
||||||
unless the property name doesn't conform to variable name syntax (eg, if it starts with a digit) or if it's a
|
unless the property name doesn't conform to variable name syntax (eg, if it starts with a digit) or if it's a
|
||||||
"public" property and therefore I can't risk Google's Closure Compiler "minifying" the property name to something
|
"public" property and therefore I can't risk Google's Closure Compiler "minifying" the property name to something
|
||||||
else.
|
else.
|
||||||
|
|
|
||||||
|
|
@ -35,36 +35,50 @@ Another exception is optional parameters. When I write a method with optional p
|
||||||
parameters to either be omitted (ie, *undefined*) or set to *null*. Using "==", you can check for either value with
|
parameters to either be omitted (ie, *undefined*) or set to *null*. Using "==", you can check for either value with
|
||||||
a single comparison:
|
a single comparison:
|
||||||
|
|
||||||
if (parameter == null) { ... }
|
``` javascript
|
||||||
|
if (parameter == null) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
whereas strict equality requires more work:
|
whereas strict equality requires more work:
|
||||||
|
|
||||||
if (parameter === undefined || parameter === null) { ... }
|
``` javascript
|
||||||
|
if (parameter === undefined || parameter === null) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
This is one of those times when coercion (of *undefined* to *null*), and the use of "non-strict" operators, is beneficial.
|
This is one of those times when coercion (of *undefined* to *null*), and the use of "non-strict" operators, is beneficial.
|
||||||
Here's another:
|
Here's another:
|
||||||
|
|
||||||
if (!b) { ... }
|
``` javascript
|
||||||
|
if (!b) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
Coercing a value to *boolean* is a popular way of checking for all "falsy" values (ie, *undefined*, *null*,
|
Coercing a value to *boolean* is a popular way of checking for all "falsy" values (ie, *undefined*, *null*,
|
||||||
0, false, "", NaN, etc). It is shorthand for:
|
0, false, "", NaN, etc). It is shorthand for:
|
||||||
|
|
||||||
if (b == false) { ... }
|
``` javascript
|
||||||
|
if (b == false) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
yet I suspect the proponents of strict equality would embrace the former while rejecting the latter.
|
yet I suspect the proponents of strict equality would embrace the former while rejecting the latter.
|
||||||
|
|
||||||
However, I don't recommend "falsy" checks for optional parameters:
|
However, I don't recommend "falsy" checks for optional parameters:
|
||||||
|
|
||||||
if (!parameter) { ... }
|
``` javascript
|
||||||
|
if (!parameter) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
because often a valid numeric parameter might include 0, or a valid string parameter might include "", so it's better
|
because often a valid numeric parameter might include 0, or a valid string parameter might include "", so it's better
|
||||||
to do this:
|
to do this:
|
||||||
|
|
||||||
if (parameter == null) { ... }
|
``` javascript
|
||||||
|
if (parameter == null) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
and obviously if *null* is also a acceptable value, then you should definitely use strict equality:
|
and obviously if *null* is also a acceptable value, then you should definitely use strict equality:
|
||||||
|
|
||||||
if (parameter === undefined) { ... }
|
``` javascript
|
||||||
|
if (parameter === undefined) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
Problems with type coercion are **NOT** problems caused by a poor choice of operators, so trying to make
|
Problems with type coercion are **NOT** problems caused by a poor choice of operators, so trying to make
|
||||||
those problems go away by artificially limiting your choice of operators seems like the wrong solution.
|
those problems go away by artificially limiting your choice of operators seems like the wrong solution.
|
||||||
|
|
@ -78,18 +92,20 @@ Explicitly convert variables to a single type whenever possible. For example, I
|
||||||
that accepts an optional numeric parameter, with a documented default value when it's omitted. I think it's
|
that accepts an optional numeric parameter, with a documented default value when it's omitted. I think it's
|
||||||
important make that parameter unambiguously numeric as soon as possible; eg:
|
important make that parameter unambiguously numeric as soon as possible; eg:
|
||||||
|
|
||||||
/**
|
``` javascript
|
||||||
* foo(n)
|
/**
|
||||||
*
|
* foo(n)
|
||||||
* Performs a mathematical operation on n and returns a result.
|
*
|
||||||
*
|
* Performs a mathematical operation on n and returns a result.
|
||||||
* @param {number} [n] is an optional parameter (defaults to zero if omitted)
|
*
|
||||||
* @return {number}
|
* @param {number} [n] is an optional parameter (defaults to zero if omitted)
|
||||||
*/
|
* @return {number}
|
||||||
function foo(n) {
|
*/
|
||||||
n = n || 0;
|
function foo(n) {
|
||||||
...
|
n = n || 0;
|
||||||
}
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
The expression `n || 0` might seem pointless, because *undefined* and *zero* are equivalent in a "falsy" sense, but
|
The expression `n || 0` might seem pointless, because *undefined* and *zero* are equivalent in a "falsy" sense, but
|
||||||
*undefined* is not a number, and there will be fewer problems downstream if you ensure that n is *always* a number.
|
*undefined* is not a number, and there will be fewer problems downstream if you ensure that n is *always* a number.
|
||||||
|
|
@ -98,8 +114,10 @@ The expression `n || 0` might seem pointless, because *undefined* and *zero* are
|
||||||
|
|
||||||
When using *for*...*in* loops like this:
|
When using *for*...*in* loops like this:
|
||||||
|
|
||||||
var a = [100, 200, 300];
|
``` javascript
|
||||||
for (var i in a) { ... }
|
var a = [100, 200, 300];
|
||||||
|
for (var i in a) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
the type of variable *i* will be **string** rather than **number**; that is, it will contain "0", "1", and "2" rather
|
the type of variable *i* will be **string** rather than **number**; that is, it will contain "0", "1", and "2" rather
|
||||||
than 0, 1, and 2. If you then use *i* to set a matching element in another array, that element will not be stored in
|
than 0, 1, and 2. If you then use *i* to set a matching element in another array, that element will not be stored in
|
||||||
|
|
@ -107,27 +125,35 @@ the same (numeric) position as the original array.
|
||||||
|
|
||||||
One solution is to convert *i* to a **number**:
|
One solution is to convert *i* to a **number**:
|
||||||
|
|
||||||
parseInt(i, 10);
|
``` javascript
|
||||||
|
parseInt(i, 10);
|
||||||
|
```
|
||||||
|
|
||||||
However, a more elegant solution is to use the unary "+" operator to coerce the **string** to a **number**:
|
However, a more elegant solution is to use the unary "+" operator to coerce the **string** to a **number**:
|
||||||
|
|
||||||
+i;
|
``` javascript
|
||||||
|
+i;
|
||||||
|
```
|
||||||
|
|
||||||
The same problem arises with objects using numeric properties. And watch out for JavaScript's automatic base
|
The same problem arises with objects using numeric properties. And watch out for JavaScript's automatic base
|
||||||
conversion of numeric properties. For example, when you enumerate the properties of object "o":
|
conversion of numeric properties. For example, when you enumerate the properties of object "o":
|
||||||
|
|
||||||
var o = {
|
``` javascript
|
||||||
0x20: ' ',
|
var o = {
|
||||||
0x41: 'A'
|
0x20: ' ',
|
||||||
};
|
0x41: 'A'
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
you will get the strings "32" and "65", not "0x20" and "0x41". You must quote your property names to prevent
|
you will get the strings "32" and "65", not "0x20" and "0x41". You must quote your property names to prevent
|
||||||
any conversion; eg:
|
any conversion; eg:
|
||||||
|
|
||||||
var o = {
|
``` javascript
|
||||||
"0x20": ' ',
|
var o = {
|
||||||
"0x41": 'A'
|
"0x20": ' ',
|
||||||
};
|
"0x41": 'A'
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Numeric properties can always be safely converted using the unary "+" operator, regardless whether they were quoted
|
Numeric properties can always be safely converted using the unary "+" operator, regardless whether they were quoted
|
||||||
or not.
|
or not.
|
||||||
|
|
@ -141,8 +167,10 @@ whereas unary "+" conversion will return *NaN* if there are any invalid digits i
|
||||||
It turns out that shifting an integer value by more than 31 bits in either direction may not shift as many bits as
|
It turns out that shifting an integer value by more than 31 bits in either direction may not shift as many bits as
|
||||||
you'd expect. For example:
|
you'd expect. For example:
|
||||||
|
|
||||||
n = 0x10000000;
|
``` javascript
|
||||||
n >>>= 33;
|
n = 0x10000000;
|
||||||
|
n >>>= 33;
|
||||||
|
```
|
||||||
|
|
||||||
will shift n by only *one* bit, not 33 bits, and the result will be 0x08000000, not zero. This is because,
|
will shift n by only *one* bit, not 33 bits, and the result will be 0x08000000, not zero. This is because,
|
||||||
just like the shift instructions on 32-bit Intel processors, JavaScript converts the shift count to a *mod 32* value
|
just like the shift instructions on 32-bit Intel processors, JavaScript converts the shift count to a *mod 32* value
|
||||||
|
|
@ -150,17 +178,23 @@ just like the shift instructions on 32-bit Intel processors, JavaScript converts
|
||||||
|
|
||||||
So the above example is equivalent to:
|
So the above example is equivalent to:
|
||||||
|
|
||||||
n >>>= 1;
|
``` javascript
|
||||||
|
n >>>= 1;
|
||||||
|
```
|
||||||
|
|
||||||
If you really need larger shift counts to work in a consistent manner, you can perform multiple shifts, where each
|
If you really need larger shift counts to work in a consistent manner, you can perform multiple shifts, where each
|
||||||
shift count is in the range 0-31. Here's one way to shift a number 33 bits:
|
shift count is in the range 0-31. Here's one way to shift a number 33 bits:
|
||||||
|
|
||||||
n = (n >>> 31) >>> 2;
|
``` javascript
|
||||||
|
n = (n >>> 31) >>> 2;
|
||||||
|
```
|
||||||
|
|
||||||
Also, it's not quite correct to say that a shift count of zero has *no* effect on a number:
|
Also, it's not quite correct to say that a shift count of zero has *no* effect on a number:
|
||||||
|
|
||||||
n = 0x88888888|0; // n is displayed as -2004318072
|
``` javascript
|
||||||
n >>>= 0; // n is displayed as 2290649224
|
n = 0x88888888|0; // n is displayed as -2004318072
|
||||||
|
n >>>= 0; // n is displayed as 2290649224
|
||||||
|
```
|
||||||
|
|
||||||
It's true that the bottom 32 bits of the number were not changed, but a side-effect of the unsigned shift operator
|
It's true that the bottom 32 bits of the number were not changed, but a side-effect of the unsigned shift operator
|
||||||
is that all the upper sign bits are stripped from the (64-bit) result.
|
is that all the upper sign bits are stripped from the (64-bit) result.
|
||||||
|
|
@ -168,7 +202,9 @@ is that all the upper sign bits are stripped from the (64-bit) result.
|
||||||
Similarly, as soon as you perform any other bitwise operation on the number, even one that does not modify the low
|
Similarly, as soon as you perform any other bitwise operation on the number, even one that does not modify the low
|
||||||
32 bits, the upper bits will revert to the sign of the lower 32-bit value:
|
32 bits, the upper bits will revert to the sign of the lower 32-bit value:
|
||||||
|
|
||||||
n |= 0; // n is displayed as -2004318072 again
|
``` javascript
|
||||||
|
n |= 0; // n is displayed as -2004318072 again
|
||||||
|
```
|
||||||
|
|
||||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||||
*March 26, 2015*
|
*March 26, 2015*
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* Syntax highlighting styles
|
* Syntax highlighting styles
|
||||||
*/
|
*/
|
||||||
.highlight {
|
.highlight {
|
||||||
background: #fff;
|
// background: #fff;
|
||||||
@extend %vertical-rhythm;
|
@extend %vertical-rhythm;
|
||||||
|
|
||||||
.c { color: #998; font-style: italic } // Comment
|
.c { color: #998; font-style: italic } // Comment
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue