diff --git a/_config.yml b/_config.yml index 9d3b8d542..474115932 100644 --- a/_config.yml +++ b/_config.yml @@ -17,7 +17,7 @@ right_brace: "}" # 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 kramdown: input: GFM diff --git a/_posts/2014-09-30-pcjs-coding-conventions.md b/_posts/2014-09-30-pcjs-coding-conventions.md index a6d7eb77a..eceae0cc0 100644 --- a/_posts/2014-09-30-pcjs-coding-conventions.md +++ b/_posts/2014-09-30-pcjs-coding-conventions.md @@ -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, *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 "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 want the ChipSet constructor becoming littered with property constants, I first define a constant object; in this case, **PIC_LO**: - ChipSet.PIC_LO = {}; - ChipSet.PIC_LO.OCW2_EOI = 0x20; // non-specific EOI (end-of-interrupt) - ChipSet.PIC_LO.OCW2_EOI_SPEC = 0x60; // 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 +``` javascript +ChipSet.PIC_LO = {}; +ChipSet.PIC_LO.OCW2_EOI = 0x20; // non-specific EOI (end-of-interrupt) +ChipSet.PIC_LO.OCW2_EOI_SPEC = 0x60; // 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*) that's also easier to preprocess. However, I've gradually switched to the more conventional JavaScript object notation for class constants: - ChipSet.PIC_LO = { - OCW2_EOI: 0x20, // non-specific EOI (end-of-interrupt) - OCW2_EOI_SPEC: 0x60, // specific EOI - OCW2_EOI_ROT: 0xA0, // rotate on non-specific EOI - OCW2_EOI_ROTSPEC: 0xE0 // rotate on specific EOI - }; +``` javascript +ChipSet.PIC_LO = { + OCW2_EOI: 0x20, // non-specific EOI (end-of-interrupt) + OCW2_EOI_SPEC: 0x60, // 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 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: - if (DEBUG) { - [code to be removed by the Closure Compiler] - } +``` javascript +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: - 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: - 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) 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: - obj.prop = true; - +``` javascript +obj.prop = true; +``` + 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 "public" property and therefore I can't risk Google's Closure Compiler "minifying" the property name to something else. diff --git a/_posts/2015-03-26-javascript-idiosyncrasies.md b/_posts/2015-03-26-javascript-idiosyncrasies.md index 7bceb98fa..e604ddb84 100644 --- a/_posts/2015-03-26-javascript-idiosyncrasies.md +++ b/_posts/2015-03-26-javascript-idiosyncrasies.md @@ -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 a single comparison: - if (parameter == null) { ... } - +``` javascript +if (parameter == null) { ... } +``` + 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. 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*, 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. 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 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: - 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 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 important make that parameter unambiguously numeric as soon as possible; eg: - /** - * foo(n) - * - * Performs a mathematical operation on n and returns a result. - * - * @param {number} [n] is an optional parameter (defaults to zero if omitted) - * @return {number} - */ - function foo(n) { - n = n || 0; - ... - } +``` javascript +/** + * foo(n) + * + * Performs a mathematical operation on n and returns a result. + * + * @param {number} [n] is an optional parameter (defaults to zero if omitted) + * @return {number} + */ +function foo(n) { + n = n || 0; + ... +} +``` 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. @@ -98,8 +114,10 @@ The expression `n || 0` might seem pointless, because *undefined* and *zero* are When using *for*...*in* loops like this: - var a = [100, 200, 300]; - for (var i in a) { ... } +``` javascript +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 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**: - 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**: - +i; +``` javascript ++i; +``` 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": - var o = { - 0x20: ' ', - 0x41: 'A' - }; +``` javascript +var o = { + 0x20: ' ', + 0x41: 'A' +}; +``` you will get the strings "32" and "65", not "0x20" and "0x41". You must quote your property names to prevent any conversion; eg: - var o = { - "0x20": ' ', - "0x41": 'A' - }; +``` javascript +var o = { + "0x20": ' ', + "0x41": 'A' +}; +``` Numeric properties can always be safely converted using the unary "+" operator, regardless whether they were quoted 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 you'd expect. For example: - n = 0x10000000; - n >>>= 33; +``` javascript +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, 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: - 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 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: - n = 0x88888888|0; // n is displayed as -2004318072 - n >>>= 0; // n is displayed as 2290649224 +``` javascript +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 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 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)* *March 26, 2015* diff --git a/_sass/_syntax-highlighting.scss b/_sass/_syntax-highlighting.scss index 2c56e0915..fb889cc66 100644 --- a/_sass/_syntax-highlighting.scss +++ b/_sass/_syntax-highlighting.scss @@ -2,7 +2,7 @@ * Syntax highlighting styles */ .highlight { - background: #fff; +// background: #fff; @extend %vertical-rhythm; .c { color: #998; font-style: italic } // Comment