public CompilationModule(UdonSharpProgramAsset sourceAsset)
 {
     programAsset           = sourceAsset;
     resolver               = new ResolverContext();
     moduleSymbols          = new SymbolTable(resolver, null);
     moduleLabels           = new LabelTable();
     fieldsWithInitializers = new HashSet <FieldDeclarationSyntax>();
 }
        public ClassVisitor(ResolverContext resolver, SymbolTable rootTable, LabelTable labelTable)
            : base(SyntaxWalkerDepth.Node)
        {
            visitorContext = new ASTVisitorContext(resolver, rootTable, labelTable);
            methodVisitor  = new MethodVisitor(resolver, rootTable, labelTable);

            classDefinition = new ClassDefinition();
        }
Example #3
0
        private List <ClassDefinition> BuildClassDefinitions()
        {
            string[] udonSharpDataAssets = AssetDatabase.FindAssets($"t:{typeof(UdonSharpProgramAsset).Name}");

            List <UdonSharpProgramAsset> udonSharpPrograms = new List <UdonSharpProgramAsset>();

            foreach (string dataGuid in udonSharpDataAssets)
            {
                udonSharpPrograms.Add(AssetDatabase.LoadAssetAtPath <UdonSharpProgramAsset>(AssetDatabase.GUIDToAssetPath(dataGuid)));
            }

            List <ClassDefinition> classDefinitions = new List <ClassDefinition>();

            foreach (UdonSharpProgramAsset udonSharpProgram in udonSharpPrograms)
            {
                if (udonSharpProgram.sourceCsScript == null)
                {
                    continue;
                }

                string sourcePath    = AssetDatabase.GetAssetPath(udonSharpProgram.sourceCsScript);
                string programSource = UdonSharpUtils.ReadFileTextSync(sourcePath);

                ResolverContext resolver     = new ResolverContext();
                SymbolTable     classSymbols = new SymbolTable(resolver, null);

                classSymbols.OpenSymbolTable();

                LabelTable classLabels = new LabelTable();

                SyntaxTree tree = CSharpSyntaxTree.ParseText(programSource);

                ClassVisitor classVisitor = new ClassVisitor(resolver, classSymbols, classLabels);

                try
                {
                    classVisitor.Visit(tree.GetRoot());
                }
                catch (System.Exception e)
                {
                    UdonSharpUtils.LogBuildError($"{e.GetType()}: {e.Message}", sourcePath.Replace("/", "\\"), 0, 0);

                    return(null);
                }

                classSymbols.CloseSymbolTable();

                classVisitor.classDefinition.classScript = udonSharpProgram.sourceCsScript;
                classDefinitions.Add(classVisitor.classDefinition);
            }

            return(classDefinitions);
        }
        // Resolve any labels that didn't have addresses at the time of creation
        public string GetAssemblyStr(LabelTable labelTable = null)
        {
            if (labelTable == null)
            {
                return(assemblyTextBuilder.ToString());
            }

            string assemblyString = assemblyTextBuilder.ToString();

#if !USE_UDON_LABELS
            assemblyString = ReplaceLabels(assemblyString, labelTable);
#endif

            return(assemblyString);
        }
Example #5
0
        // Resolve any labels that didn't have addresses at the time of creation
        public string GetAssemblyStr(LabelTable labelTable = null)
        {
            if (labelTable == null)
            {
                return(assemblyTextBuilder.ToString());
            }

            string assemblyString = assemblyTextBuilder.ToString();

            currentLabelTable = labelTable;

            assemblyString = Regex.Replace(assemblyString, @"(?<whitespace>\s*)(?<labeltype>JUMP_LABEL,|JUMP_IF_FALSE_LABEL,)\s*[[](?<label>[a-zA-Z_\d]+)[\]](?<commentwhitespace>\s*)(?<comment>[#]+\s*[a-zA-Z#\s]+)*", MatchEval);

            currentLabelTable = null;

            return(assemblyString);
        }
        public CompilationModule(UdonSharpProgramAsset sourceAsset)
        {
            programAsset           = sourceAsset;
            resolver               = new ResolverContext();
            moduleSymbols          = new SymbolTable(resolver, null);
            moduleLabels           = new LabelTable();
            fieldsWithInitializers = new HashSet <FieldDeclarationSyntax>();

            if (programAsset.sourceCsScript == null)
            {
                throw new System.ArgumentException($"Asset '{AssetDatabase.GetAssetPath(programAsset)}' does not have a valid program source to compile from");
            }


            sourceCode = UdonSharpUtils.ReadFileTextSync(AssetDatabase.GetAssetPath(programAsset.sourceCsScript));

            settings = UdonSharpSettings.GetSettings();
        }
        private string ReplaceLabels(string assemblyString, LabelTable labelTable)
        {
            StringBuilder newAssemblyBuilder = new StringBuilder();

            using (StringReader reader = new StringReader(assemblyString))
            {
                string currentLine = reader.ReadLine();

                while (currentLine != null)
                {
                    string line = currentLine.TrimStart(' ', '\n', '\r');
                    if (line.StartsWith("JUMP_LABEL,"))
                    {
                        int       startIdx  = line.IndexOf('[') + 1;
                        int       endIdx    = line.IndexOf(']');
                        string    labelName = line.Substring(startIdx, endIdx - startIdx);
                        JumpLabel label     = labelTable.GetLabel(labelName);
                        newAssemblyBuilder.Append($"        JUMP, {label.AddresStr()}\n");
                    }
                    else if (line.StartsWith("JUMP_IF_FALSE_LABEL,"))
                    {
                        int       startIdx  = line.IndexOf('[') + 1;
                        int       endIdx    = line.IndexOf(']');
                        string    labelName = line.Substring(startIdx, endIdx - startIdx);
                        JumpLabel label     = labelTable.GetLabel(labelName);
                        newAssemblyBuilder.Append($"        JUMP_IF_FALSE, {label.AddresStr()}\n");
                    }
                    else
                    {
                        newAssemblyBuilder.Append(currentLine + "\n");
                    }

                    currentLine = reader.ReadLine();
                }
            }

            return(newAssemblyBuilder.ToString());
        }
 public MethodVisitor(ResolverContext resolver, SymbolTable rootTable, LabelTable labelTable)
     : base(SyntaxWalkerDepth.Node)
 {
     visitorContext = new ASTVisitorContext(resolver, rootTable, labelTable);
 }