Squashed 'third_party/pico-sdk/' content from commit 2062372d2

Change-Id: Ic20f199d3ed0ea8d3a6a1bbf513f875ec7500cc6
git-subtree-dir: third_party/pico-sdk
git-subtree-split: 2062372d203b372849d573f252cf7c6dc2800c0a
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/tools/pioasm/lexer.ll b/tools/pioasm/lexer.ll
new file mode 100644
index 0000000..939b06f
--- /dev/null
+++ b/tools/pioasm/lexer.ll
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+%{ /* -*- C++ -*- */
+# include <cerrno>
+# include <climits>
+# include <cstdlib>
+# include <cstring>
+# include <string>
+# include "pio_assembler.h"
+# include "parser.hpp"
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4996) // fopen
+#endif
+
+%}
+
+%option noyywrap nounput noinput batch debug never-interactive case-insensitive noline
+
+%{
+  yy::parser::symbol_type make_INT(const std::string &s, const yy::parser::location_type& loc);
+  yy::parser::symbol_type make_HEX(const std::string &s, const yy::parser::location_type& loc);
+  yy::parser::symbol_type make_BINARY(const std::string &s, const yy::parser::location_type& loc);
+%}
+
+blank         [ \t]
+whitesp       {blank}+
+
+comment       (";"|"//")[^\n]*
+
+digit         [0-9]
+id            [a-zA-Z_][a-zA-Z0-9_]*
+
+binary        "0b"[01]+
+int           {digit}+
+hex	          "0x"[0-9a-fA-F]+
+directive     \.{id}
+
+output_fmt    [^%\n]+
+
+%{
+  // Code run each time a pattern is matched.
+  # define YY_USER_ACTION  loc.columns (yyleng);
+%}
+
+%x code_block
+%x c_comment
+%x lang_opt
+
+%%
+        std::string code_block_contents;
+        yy::location code_block_start;
+%{
+  // A handy shortcut to the location held by the pio_assembler.
+  yy::location& loc = pioasm.location;
+  // Code run each time yylex is called.
+  loc.step();
+%}
+
+{blank}+                            loc.step();
+\n+                                 { auto loc_newline = loc; loc_newline.end = loc_newline.begin; loc.lines(yyleng); loc.step(); return yy::parser::make_NEWLINE(loc_newline); }
+
+"%"{blank}*{output_fmt}{blank}*"{"  {
+                                        BEGIN(code_block);
+                                        code_block_contents = "";
+                                        code_block_start = loc;
+                                        std::string tmp(yytext);
+                                        tmp = tmp.substr(1, tmp.length() - 2);
+                                        tmp = tmp.erase(0, tmp.find_first_not_of(" \t"));
+                                        tmp = tmp.erase(tmp.find_last_not_of(" \t") + 1);
+                                        return yy::parser::make_CODE_BLOCK_START( tmp, loc);
+                                    }
+<code_block>{
+    {blank}+                        loc.step();
+    \n+                             { auto loc_newline = loc; loc_newline.end = loc_newline.begin; loc.lines(yyleng); loc.step(); }
+    "%}"                            { BEGIN(INITIAL); auto loc2 = loc; loc2.begin = code_block_start.begin; return yy::parser::make_CODE_BLOCK_CONTENTS(code_block_contents, loc2); }
+    .*                              { code_block_contents += std::string(yytext) + "\n"; }
+}
+
+<c_comment>{
+    {blank}+                        loc.step();
+    "*/"                            { BEGIN(INITIAL); }
+    "*"                             { }
+    [^\n\*]*                        { }
+    \n+                             { auto loc_newline = loc; loc_newline.end = loc_newline.begin; loc.lines(yyleng); loc.step(); }
+}
+
+<lang_opt>{
+\"[^\n]*\"                          return yy::parser::make_STRING(yytext, loc);
+{blank}+                            loc.step();
+"="		                            return yy::parser::make_EQUAL(loc);
+{int}                               return make_INT(yytext, loc);
+{hex}                               return make_HEX(yytext, loc);
+{binary}                            return make_BINARY(yytext, loc);
+[^ \t\n\"=]+                         return yy::parser::make_NON_WS(yytext, loc);
+\n+                                 { BEGIN(INITIAL); auto loc_newline = loc; loc_newline.end = loc_newline.begin; loc.lines(yyleng); loc.step(); return yy::parser::make_NEWLINE(loc_newline);  }
+.                                   { throw yy::parser::syntax_error(loc, "invalid character: " + std::string(yytext)); }
+}
+
+"/*"                                { BEGIN(c_comment); }
+","	                                return yy::parser::make_COMMA(loc);
+"::"                                return yy::parser::make_REVERSE(loc);
+":"	                                return yy::parser::make_COLON(loc);
+"["                                 return yy::parser::make_LBRACKET(loc);
+"]"                                 return yy::parser::make_RBRACKET(loc);
+"("                                 return yy::parser::make_LPAREN(loc);
+")"                                 return yy::parser::make_RPAREN(loc);
+"+"                                 return yy::parser::make_PLUS(loc);
+"--"                                return yy::parser::make_POST_DECREMENT(loc);
+"−−"                                return yy::parser::make_POST_DECREMENT(loc);
+"-"                                 return yy::parser::make_MINUS(loc);
+"*"                                 return yy::parser::make_MULTIPLY(loc);
+"/"                                 return yy::parser::make_DIVIDE(loc);
+"|"                                 return yy::parser::make_OR(loc);
+"&"                                 return yy::parser::make_AND(loc);
+"^"                                 return yy::parser::make_XOR(loc);
+"!="		                        return yy::parser::make_NOT_EQUAL(loc);
+"!"			                        return yy::parser::make_NOT(loc);
+"~"			                        return yy::parser::make_NOT(loc);
+
+".program"		                    return yy::parser::make_PROGRAM(loc);
+".wrap_target"	                    return yy::parser::make_WRAP_TARGET(loc);
+".wrap"			                    return yy::parser::make_WRAP(loc);
+".word"			                    return yy::parser::make_WORD(loc);
+".define"		                    return yy::parser::make_DEFINE(loc);
+".side_set"		                    return yy::parser::make_SIDE_SET(loc);
+".origin"		                    return yy::parser::make_ORIGIN(loc);
+".lang_opt"         	            { BEGIN(lang_opt); return yy::parser::make_LANG_OPT(loc); }
+{directive}                         return yy::parser::make_UNKNOWN_DIRECTIVE(yytext, loc);
+
+"JMP"			                    return yy::parser::make_JMP(loc);
+"WAIT"			                    return yy::parser::make_WAIT(loc);
+"IN"			                    return yy::parser::make_IN(loc);
+"OUT"			                    return yy::parser::make_OUT(loc);
+"PUSH"			                    return yy::parser::make_PUSH(loc);
+"PULL"			                    return yy::parser::make_PULL(loc);
+"MOV"			                    return yy::parser::make_MOV(loc);
+"IRQ"			                    return yy::parser::make_IRQ(loc);
+"SET"			                    return yy::parser::make_SET(loc);
+"NOP"			                    return yy::parser::make_NOP(loc);
+
+"PUBLIC"		                    return yy::parser::make_PUBLIC(loc);
+
+"OPTIONAL"		                    return yy::parser::make_OPTIONAL(loc);
+"OPT"			                    return yy::parser::make_OPTIONAL(loc);
+"SIDE"			                    return yy::parser::make_SIDE(loc);
+"SIDESET"	                        return yy::parser::make_SIDE(loc);
+"SIDE_SET"   	                    return yy::parser::make_SIDE(loc);
+"PIN"			                    return yy::parser::make_PIN(loc);
+"GPIO"			                    return yy::parser::make_GPIO(loc);
+"OSRE"			                    return yy::parser::make_OSRE(loc);
+
+"PINS"			                    return yy::parser::make_PINS(loc);
+"NULL"			                    return yy::parser::make_NULL(loc);
+"PINDIRS"		                    return yy::parser::make_PINDIRS(loc);
+"X"	    		                    return yy::parser::make_X(loc);
+"Y"		    	                    return yy::parser::make_Y(loc);
+"PC"			                    return yy::parser::make_PC(loc);
+"EXEC"			                    return yy::parser::make_EXEC(loc);
+"ISR"			                    return yy::parser::make_ISR(loc);
+"OSR"			                    return yy::parser::make_OSR(loc);
+"STATUS"		                    return yy::parser::make_STATUS(loc);
+
+"BLOCK"			                    return yy::parser::make_BLOCK(loc);
+"NOBLOCK"		                    return yy::parser::make_NOBLOCK(loc);
+"IFFULL"		                    return yy::parser::make_IFFULL(loc);
+"IFEMPTY"		                    return yy::parser::make_IFEMPTY(loc);
+"REL"			                    return yy::parser::make_REL(loc);
+
+"CLEAR"			                    return yy::parser::make_CLEAR(loc);
+"NOWAIT"		                    return yy::parser::make_NOWAIT(loc);
+
+"ONE"                               return yy::parser::make_INT(1, loc);
+"ZERO"                              return yy::parser::make_INT(0, loc);
+
+<<EOF>>                             return yy::parser::make_END(loc);
+
+{int}                               return make_INT(yytext, loc);
+{hex}                               return make_HEX(yytext, loc);
+{binary}                            return make_BINARY(yytext, loc);
+
+{id}                                return yy::parser::make_ID(yytext, loc);
+
+{comment}                           { }
+
+.                                   { throw yy::parser::syntax_error(loc, "invalid character: " + std::string(yytext)); }
+
+%%
+
+yy::parser::symbol_type make_INT(const std::string &s, const yy::parser::location_type& loc)
+{
+  errno = 0;
+  long n = strtol (s.c_str(), NULL, 10);
+  if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE))
+    throw yy::parser::syntax_error (loc, "integer is out of range: " + s);
+  return yy::parser::make_INT((int) n, loc);
+}
+
+yy::parser::symbol_type make_HEX(const std::string &s, const yy::parser::location_type& loc)
+{
+  errno = 0;
+  long n = strtol (s.c_str() + 2, NULL, 16);
+  if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE))
+    throw yy::parser::syntax_error (loc, "hex is out of range: " + s);
+  return yy::parser::make_INT((int) n, loc);
+}
+
+yy::parser::symbol_type make_BINARY(const std::string &s, const yy::parser::location_type& loc)
+{
+  errno = 0;
+  long n = strtol (s.c_str()+2, NULL, 2);
+  if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE))
+    throw yy::parser::syntax_error (loc, "binary is out of range: " + s);
+  return yy::parser::make_INT((int) n, loc);
+}
+
+void pio_assembler::scan_begin ()
+{
+  yy_flex_debug = false;
+  if (source.empty () || source == "-")
+    yyin = stdin;
+  else if (!(yyin = fopen (source.c_str (), "r")))
+    {
+      std::cerr << "cannot open " << source << ": " << strerror(errno) << '\n';
+      exit (EXIT_FAILURE);
+    }
+}
+
+void pio_assembler::scan_end ()
+{
+  fclose (yyin);
+}