Permalink
Browse files

Incomplete 3rd revision parser; reads tests/assignment.js correctly s…

…o far
  • Loading branch information...
1 parent 079c492 commit 4d225d32cdf98b3770bc19750badd778a1c2550a @csnover committed Jul 17, 2011
View
@@ -0,0 +1 @@
+*.komodoproject
View
@@ -0,0 +1,6 @@
+[submodule "dojo"]
+ path = dojo
+ url = https://github.com/dojo/dojo.git
+[submodule "uglify-js"]
+ path = uglify-js
+ url = https://github.com/mishoo/UglifyJS.git
Submodule dojo added at 836f07
@@ -0,0 +1,23 @@
+define([], function () {
+ /**
+ * A complex expression that cannot be easily represented by static analysis.
+ * @param tokens @see ComplexExpression#tokens
+ */
+ function ComplexExpression(tokens) {
+ if (!(this instanceof ComplexExpression)) {
+ return new ComplexExpression(tokens);
+ }
+
+ this.tokens = tokens;
+ return this; // strict mode
+ }
+ ComplexExpression.prototype = {
+ constructor: ComplexExpression,
+
+ /**
+ * @type Array.<Object> An array of tokens from the tokenizer.
+ */
+ tokens: []
+ }
+ return ComplexExpression;
+});
View
@@ -0,0 +1,75 @@
+define([ './env' ], function (env) {
+ // from dojo loader
+ function resolveRelativeId(path) {
+ var result = [], segment, lastSegment;
+ path = path.split('/');
+ while (path.length) {
+ segment = path.shift();
+ if (segment === '..' && result.length && lastSegment != '..') {
+ result.pop();
+ }
+ else if(segment != '.') {
+ result.push((lastSegment = segment));
+ } // else ignore '.'
+ }
+
+ return result.join('/');
+ }
+
+ function getModuleIdFromPath(path) {
+ var result = resolveRelativeId(path),
+ match = false;
+
+ for (var module in env.config.prefixMap) {
+ var pathPrefix = env.config.baseUrl + env.config.prefixMap[module];
+
+ // avoid accidental matching of partial paths
+ if (pathPrefix.charAt(-1) !== '/') {
+ pathPrefix += '/';
+ }
+
+ if (result.indexOf(pathPrefix) === 0) {
+ result = result.substr(pathPrefix.length);
+ match = true;
+ break;
+ }
+ }
+
+ result = result.replace(/^\/|\.js$/g, '');
+
+ // TODO: Update to use more traditional AMD module map pattern
+ return !match ? result : (result === 'main' ? module : module + '/' + result);
+ }
+
+ function File(filename) {
+ if (!(this instanceof File)) {
+ return new File(filename);
+ }
+
+ this.filename = filename;
+ this.moduleId = getModuleIdFromPath(filename);
+ return this;
+ }
+
+ File.prototype = {
+ constructor: File,
+
+ /**
+ * The absolute filename of the current file.
+ * @type string
+ */
+ filename: undefined,
+
+ /**
+ * The module ID based on the provided filename.
+ * @type string
+ */
+ moduleId: undefined,
+
+ toString: function () {
+ return '[object File(filename: ' + this.filename + ', moduleId: ' + this.moduleId + ')]';
+ }
+ };
+
+ return File;
+});
View
@@ -0,0 +1,49 @@
+define([ './Value' ], function (Value) {
+ var _moduleMap = {};
+
+ /**
+ * Represents an AMD module.
+ */
+ function Module(id) {
+ if (!(this instanceof Module)) {
+ return _moduleMap[id] || new Module(id);
+ }
+
+ this.id = id;
+ this.dependencies = [];
+ this.extends = [];
+ this.value = new Value();
+
+ _moduleMap[id] = this;
+ return this; // strict mode
+ }
+ Module.prototype = {
+ constructor: Module,
+
+ /**
+ * Globally resolvable module ID.
+ * @type string?
+ */
+ id: undefined,
+
+ /**
+ * Array of modules that this module depends upon.
+ * @type Array.<string|Module>
+ */
+ dependencies: [],
+
+ /**
+ * Other modules that are extended when this module is loaded.
+ * @type Array.<string|Module>
+ */
+ extends: [],
+
+ /**
+ * The value of the module.
+ * @type Value
+ */
+ value: undefined
+ };
+
+ return Module;
+});
View
@@ -0,0 +1,15 @@
+define([ './env' ], function (env) {
+ /**
+ * A reference to another variable. Resolved in pass XXX: TODOC
+ */
+ function Reference(toVar) {
+ if (!(this instanceof Reference)) {
+ return new Reference(toVar);
+ }
+
+ this.toVar = toVar;
+ return this; // strict mode
+ }
+
+ return Reference;
+});
View
@@ -0,0 +1,94 @@
+define([ 'dojo/_base/lang', './env', './Variable' ], function (lang, env, Variable) {
+ /**
+ * A variable scope.
+ */
+ function Scope(parent) {
+ if (!(this instanceof Scope)) {
+ return new Scope(parent);
+ }
+
+ if (!parent) {
+ parent = env.scope;
+ }
+
+ this.parent = parent;
+ this.children = [];
+ this.vars = {};
+
+ return this; // strict mode
+ }
+ Scope.prototype = {
+ constructor: Scope,
+
+ /**
+ * If a scope has no parent, it is the global scope.
+ * @type Scope?
+ */
+ parent: undefined,
+
+ /**
+ * Child scopes.
+ * @type Array.<Scope>
+ */
+ children: [],
+
+ /**
+ * @type Array.<ScopeVariable>
+ */
+ vars: {},
+
+ /**
+ * Creates a new variable in the local scope. Called from var x, ….
+ */
+ addVariable: function (/**string*/ name) {
+ if (this.vars[name]) {
+ console.warn('Variable ' + name + ' already defined in current scope');
+ return this.vars[name];
+ }
+
+ console.info('Adding variable ' + name + ' to scope');
+ return this.vars[name] = new Variable();
+ },
+
+ /**
+ * Sets the property of a variable in the nearest declared scope.
+ * @param name An array of accessors, or a dot-separated accessor string like a.b.c.
+ */
+ setVariableValue: function (/**Array|string*/ name, /**Value?*/ value) {
+ if (!lang.isArray(name)) {
+ name = name.split('.');
+ }
+
+ var scope = this, variable;
+
+ // find variable in nearest scope
+ do {
+ if ((variable = scope.vars[name[0]])) {
+ break;
+ }
+ } while ((scope = this.parent));
+
+ if (!variable) {
+ console.warn(name.join('.') + ': Implicit global variable declaration');
+ variable = env.globalScope.addVariable(name[0]);
+ }
+
+ if (name.length === 1) {
+ if (variable.value) {
+ console.info(name.join('.') + ': Changing value reference');
+ }
+
+ variable.value = value;
+ }
+ else {
+ variable.setProperty(name.slice(1), value);
+ }
+ },
+
+ resolveVariables: function () {
+
+ }
+ };
+
+ return Scope;
+});
View
@@ -0,0 +1,64 @@
+define([ 'dojo/_base/kernel', './env' ], function (dojo, env) {
+ /**
+ * Represents a parsed data structure (object, etc.).
+ */
+ function Value(/** Object? */ kwArgs) {
+ if (!(this instanceof Value)) {
+ return new Value(kwArgs);
+ }
+
+ this.properties = {};
+ this.mixins = [];
+ this.returns = [];
+ this.from = env.file;
+
+ dojo.mixin(this, kwArgs);
+
+ return this; // strict mode
+ }
+ Value.prototype = {
+ constructor: Value,
+
+ /**
+ * The file that this definition came from.
+ * @type File
+ */
+ file: undefined,
+
+ /**
+ * @type string? One of 'string', 'number', 'regexp', 'function', 'instance', 'array', 'object',
+ * 'atom', undefined. If undefined, it means that the Value has not been fully resolved yet.
+ */
+ type: undefined,
+
+ /**
+ * The value of a scalar, regular expression, or Array object.
+ * @type string|number|RegExp|Array.<*>?
+ */
+ value: undefined,
+
+ /**
+ * An array of modules whose properties are mixed into this value at runtime.
+ * @type Array.<string|Module|Reference>
+ */
+ mixins: [],
+
+ /**
+ * A hash map of properties attached to this data structure.
+ * @type Object.<Module|ComplexExpression|Value|Reference>
+ */
+ properties: {},
+
+ /**
+ * If type is 'function', all return values from within the function.
+ * @type Array.<Value|ScopeReference>
+ */
+ returns: [],
+
+ toString: function () {
+ return '[object Value(type: ' + this.type + ', value: ' + this.value + ')]';
+ }
+ };
+
+ return Value;
+});
Oops, something went wrong.

0 comments on commit 4d225d3

Please sign in to comment.