最近要做數據處理,自定義了一些數據結構,比如Mat,Vector,Point之類的,對于加減乘除之類的四則運算還要重復定義,代碼顯得不是很直觀,javascript沒有運算符重載這個像C++、C#之類的功能的確令人不爽,于是想“曲線救國”,自動將翻譯代碼實現運算符重載,實現思路其實很簡單,就是編寫一個解釋器,將代碼編譯。例如:
S = A + B (B - C.fun())/2 + D
翻譯成
`S = replace(replace(A, '+', replace(replace(B,'',(replace(B,'-',C.fun())))),'/',2),'+',D)`
在replace函數中我們調用對象相應的運算符函數,replace函數代碼如下:
/** * 轉換方法 * @param a * @param op * @param b * @returns {*} * @private */export function __replace__(a,op,b){ if(typeof(a) != 'object' && typeof(b) != 'object'){ return new Function('a','b','return a' + op + 'b')(a,b) } if(!Object.getPrototypeOf(a).isPrototypeOf(b) && Object.getPrototypeOf(b).isPrototypeOf(a)){ throw '不同類型的對象不能使用四則運算' } let target = null if (Object.getPrototypeOf(a).isPrototypeOf(b)) { target = new Function('return ' + b.__proto__.constructor.name)() } if (Object.getPrototypeOf(b).isPrototypeOf(a)) { target = new Function('return ' + a.__proto__.constructor.name)() } if (op == '+') { if (target.__add__ != undefined) { return target.__add__(a, b) }else { throw target.toString() +'/n未定義__add__方法' } }else if(op == '-') { if (target.__plus__ != undefined) { return target.__plus__(a, b) }else { throw target.toString() + '/n未定義__plus__方法' } }else if(op == '*') { if (target.__multiply__ != undefined) { return target.__multiply__(a, b) }else { throw target.toString() + '/n未定義__multiply__方法' } } else if (op == '/') { if (target.__divide__ != undefined) { return target.__divide__(a, b) }else { throw target.toString() + '/n未定義__divide__方法' } } else if (op == '%') { if (target.__mod__ != undefined) { return target.__mod__(a, b) }else { throw target.toString() + '/n未定義__mod__方法' } } else if(op == '.*') { if (target.__dot_multiply__ != undefined) { return target.__dot_multiply__(a, b) }else { throw target.toString() + '/n未定義__dot_multiply__方法' } } else if(op == './') { if (target.__dot_divide__ != undefined) { return target.__dot_divide__(a, b) }else { throw target.toString() + '/n未定義__dot_divide__方法' } } else if(op == '**') { if (target.__power__ != undefined) { return target.__power__(a, b) }else { throw target.toString() + '/n未定義__power__方法' } }else { throw op + '運算符無法識別' }}replace實現非常簡單,不做過多解釋,重要的部分是如何實現代碼的編譯。大學學習數據結構時四則運算的實現就是這翻譯的基礎,略微有些差異。簡單描述一下流程:
新聞熱點
疑難解答
圖片精選